1

我正在使用 Visual Studio 2008、C#、LINQ to SQL,并使用 datbase dbml GUI 编辑器来创建数据库。我想创建一个一对多的关系,但在我的例子中,1 个对象有 2 个主键。使用 GUI edtior 我创建了关联,但是当程序运行并创建数据库时,我收到错误:

“引用的表必须有一个主键或候选键。[FK Name = Screen_Pixel]”

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

在 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")]

有任何想法吗?

4

2 回答 2

1

由于我一直在为类似的事情而苦苦挣扎,并且这个问题与我的问题很接近,因此我将在此处添加我的 2 美分,以供下一个可能遇到相同问题的灵魂(在运行时从对象模型创建数据库)。

如果您的复合键实际上不必是主键(即您只想提供组合的唯一性),则解决方案是:

  • 添加您将从外键引用的常规主键(整数标识 db 生成的列)。
  • 通过在 DataContext 上的附加步骤提供唯一性约束,例如:

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

之后提交将在尝试插入重复字段时引发异常。

于 2011-06-01T09:17:39.283 回答
0

为什么要使用多个字段作为主字段(也称为“复合主字段”)?

一些学校和书籍教授使用“复合主键”,但实际上,它们并不是一个好主意。许多软件不允许这些字段,即使允许,也很难处理。

使用单个字段主键总是更好。

我的建议是将这些字段保留为标准字段或外键,并添加一个自动分配或递增的新字段。

例子:

<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> 
于 2011-01-07T21:45:47.320 回答