简体   繁体   English

Linq-To-SQL与多个外键的关联问题

[英]Linq-To-SQL Association with Multiple Foreign Keys Problem

I'm using Visual Studio 2008, C#, LINQ to SQL, and using the datbase dbml GUI editor to create a database. 我正在使用Visual Studio 2008,C#,LINQ to SQL,并使用datbase dbml GUI编辑器来创建数据库。 I want to create a 1 to many relationship, but in my case the 1 object has 2 primary keys. 我想创建1对多关系,但是在我的情况下1对象具有2个主键。 Using the GUI edtior I created the association, but when the program runs and the database is created, I get the error: 使用GUI edtior创建了关联,但是当程序运行并创建数据库时,出现错误:

"The referenced table must have a primary or candidate key. [ FK Name = Screen_Pixel ]" “引用的表必须具有主键或候选键。[FK名称= Screen_Pixel]”

The XML created in the dbml looks like: 在dbml中创建的XML看起来像:

<Table Name="Screen">
  <Column Name="PKA1" Type="System.Int64" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" />
  <Column Name="PKA2" Type="System.Int32" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" />
  <Association Name="Screen_Pixel" Member="Pixels" ThisKey="PKA1,PKA2" OtherKey="PKB1,PKB2" Type="Pixel" />
</Table>

<Table Name="Pixel>
  <Column Name="PKB1" Type="System.Int64" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" />
  <Column Name="PKB2" Type="System.Int32" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" />
  <Column Name="PKB3" Type="System.Int32" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" />
  <Association Name="Screen_Pixel" Member="Screen" ThisKey="PKB1,PKB2" OtherKey="PKA1,PKA2" Type="Screen" IsForeignKey="true" />
</Table>  

The generated associations in C# code are: 用C#代码生成的关联为:

[Association(Name=@"Screen_Pixel", Storage=@"_Screen", ThisKey=@"PKA1,PKA2", OtherKey=@"PKB1,PKB2", IsForeignKey=true)]
[Association(Name=@"Screen_Pixel", Storage=@"_Pixels", ThisKey=@"PKB1,PKB2", OtherKey=@"PKA1,PKA2")]

Any ideas? 有任何想法吗?

Since I've been struggling with something similar and this question came close to mine, I'll add my 2 cents here for the next soul that might come by with the same problem (creating the database at runtime from the object model). 由于我一直在努力解决类似问题,并且这个问题接近我的问题,因此我将在这里添加2美分,以解决下一个可能因同一问题而产生的灵魂(在运行时从对象模型创建数据库)。

If your composite key doesn't really have to be a primary key (ie you just want to provide uniqueness of the combination) the solution is to: 如果您的组合键实际上不必一定是主键(例如,您只想提供组合的唯一性),则解决方案是:

  • add a regular primary key (integer identity db generated column) that you will reference from the foreign key. 添加一个常规主键(将由外键引用)。
  • provide uniqueness constraint with an additional step on your DataContext, eg: 提供唯一性约束,并在DataContext上增加一个步骤,例如:

     yourDataContext.ExecuteCommand("ALTER TABLE Stuff ADD UNIQUE (unique_thing_1, unique_thing_2, unique_thihng_3)"); 

afterwards submits will throw an exception when attempting to insert duplicate fields. 之后,尝试插入重复的字段时,提交将引发异常。

Why do yo use several fields for a primary field (also known as a "composite primary field") ? 为什么要使用多个字段作为主字段(也称为“复合主字段”)?

Some schools and books teach to use "Composite Primary Keys", but in reality, they are not a good idea. 一些学校和书籍教导使用“复合主键”,但是实际上,这不是一个好主意。 Many software does not allow these fields, and even if it does, it's difficult to handle. 许多软件不允许这些字段,即使允许,也很难处理。

Is always better to use a single field primary key. 最好使用单个字段的主键。

My suggestion, is to keep those fields as standard fields, or foreign keys, an add a new field , that is assigned or incremented automatically. 我的建议是将这些字段保留为标准字段或外键,并添加一个自动分配或递增的新字段

Example: 例:

<Table Name="Screen"> <Column Name="ScreenKey" Type="System.Int64" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" />

<Column Name="ScreenField1" Type="System.Int64" IsPrimaryKey="false" CanBeNull="false" UpdateCheck="Never" />

<Column Name="ScreenField2" Type="System.Int32" IsPrimaryKey="false" CanBeNull="false" UpdateCheck="Never" />

<Association Name="Screen_Pixel" Member="Pixels" ThisKey="ScreenKey" OtherKey="ScreenKey" Type="Pixel" />

</Table>

<Table Name="Pixel>

<Column Name="PixelKey" Type="System.Int64" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" />

<Column Name="ScreenKey" Type="System.Int64" IsPrimaryKey="false" CanBeNull="false" UpdateCheck="Never" />

<Column Name="PixelField1" Type="System.Int64" IsPrimaryKey="false" CanBeNull="false" UpdateCheck="Never" />

<Column Name="PixelField2" Type="System.Int32" IsPrimaryKey="false" CanBeNull="false" UpdateCheck="Never" />

<Column Name="PixelField3" Type="System.Int32" IsPrimaryKey="false" CanBeNull="false" UpdateCheck="Never" />

<Association Name="Screen_Pixel" Member="Screen" ThisKey="ScreenKey" OtherKey="ScreenKey" Type="Screen" IsForeignKey="true" />

</Table> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM