简体   繁体   中英

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. I want to create a 1 to many relationship, but in my case the 1 object has 2 primary keys. Using the GUI edtior I created the association, but when the program runs and the database is created, I get the error:

"The referenced table must have a primary or candidate key. [ FK Name = Screen_Pixel ]"

The XML created in the dbml looks like:

<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:

[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).

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:

     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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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