【问题标题】:Defining an Entity Framework 1:1 association定义实体框架 1:1 关联
【发布时间】:2010-10-03 06:34:33
【问题描述】:

我正在尝试在实体框架模型中定义两个实体(一个映射到表,另一个映射到视图 - 使用 DefinedQuery)之间的 1:1 关联。 当试图在设计器中为此定义映射时,它让我选择 (1) 表或视图来映射关联。我应该选择什么?我可以选择两个表中的任何一个,但是我不得不从该表(或视图)中为关系的每一端选择一列。我希望能够从一个表中选择一列作为关联的一端,从另一个表中选择一列作为关联的另一端,但是没有办法做到这一点。

在这里,我选择映射到“DW_WF_ClaimInfo”视图,这迫使我从该视图中选择两列——关系的每一端各一列。

我还尝试在 XML 中手动定义映射,如下所示:

<AssociationSetMapping Name="Entity1Entity2" TypeName="ClaimsModel.Entity1Entity2"
     StoreEntitySet="Entity1">
  <EndProperty Name="Entity2">
    <ScalarProperty Name="DOCUMENT" ColumnName="DOCUMENT" />
  </EndProperty>
  <EndProperty Name="Entity1">
    <ScalarProperty Name="PK_DocumentId" ColumnName="PK_DocumentId" />
  </EndProperty>
</AssociationSetMapping>

但这给出了: 错误 2010:指定为此 MSL 的一部分的“文档”列在 MetadataWorkspace 中不存在。 似乎它仍然希望两列都来自同一个表,这对我来说没有意义。

此外,如果我为每一端选择相同的键,例如:

<AssociationSetMapping Name="Entity1Entity2" TypeName="ClaimsModel.Entity1Entity2"
     StoreEntitySet="Entity1">
  <EndProperty Name="Entity2">
    <ScalarProperty Name="DOCUMENT" ColumnName="PK_DocumentId" />
  </EndProperty>
  <EndProperty Name="Entity1">
    <ScalarProperty Name="PK_DocumentId" ColumnName="PK_DocumentId" />
  </EndProperty>
</AssociationSetMapping>

然后我得到:

Error 3021: Problem in Mapping Fragment starting at line 675: Each of the following
columns in table AssignedClaims is mapped to multiple conceptual side properties:
  AssignedClaims.PK_DocumentId is mapped to
    <AssignedClaimDW_WF_ClaimInfo.DW_WF_ClaimInfo.DOCUMENT,
    AssignedClaimDW_WF_ClaimInfo.AssignedClaim.PK_DocumentId>

我没有得到什么?

【问题讨论】:

  • 有没有办法重新发布该图像?我有同样的问题,但我不确定我们的设计是否相同。

标签: .net visual-studio entity-framework ado.net


【解决方案1】:

您必须选择包含外键的表。下一步是从实体中删除该外键,因为它已经使用您刚刚创建的关系表示。

例子:

table A
-------
A_ID int
B_ID int


table B
-------
B_ID int

在这种情况下,您将在设计器中选择表 A,因为它包含外键。之后您还需要从 A 实体中删除 B_ID。

【讨论】:

    【解决方案2】:

    我正在处理一个遗留应用程序,因此添加额外的主键对我来说不是一个选项。我必须做的是将它映射为 1:(0 或 1) 而不是 1:1 以使其工作。例如,如果我有两个表,分别是 Customer 和 CustomerDetails,它们都有一个名为 CustomerID 的主键。要创建关联,我必须将其设置为 1 个客户可以与(0 或 1)个 CustomerDetails 记录相关。每次插入客户时,请务必同时插入 CustomerDetails,以便保持 1:1。

    【讨论】:

      【解决方案3】:

      我同意这种设置方式似乎违反直觉。对于任何太慢(比如我)无法得到 driAn 答案的人: 根据下面的论坛帖子,我记得我们正在处理一个实体,而不是直接处理一个表。关联在 entity 上(可以为表格建模,但不是必须的)。

      http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/2823634f-9dd1-4547-93b5-17bb8a882ac2/

      实体框架将 PROPERTIES 关联到 TABLE COLUMNS。这就是为什么我们必须删除 ENTITY 上的“外键”PROPERTY(注意:我们不是删除表列)。要在代码中引用该列,(使用 ENTITY modeling 给定的表 A 和表 B 示例),您可以编写如下内容:

      variable_A = tableAs.A_ID
      variable_B = tableAs.tableBs.B_ID
      

      第二个任务是使用实体中定义的关联来获取数据。表 A 上没有名为“B_ID”的PROPERTY

      这都是假设我理解正确:)。它至少现在对我来说是正确的。

      :-丹

      【讨论】:

        【解决方案4】:

        在实体框架中,在概念设计中不应该有外键。我相信现在 EF4 允许这样做(经过一些调整),但在 EF3.5 中却不能完成。

        要解决此问题,只需删除 EF 设计器中代表外键的所有属性。不要删除主键!

        如果您随后收到 “Association end is not mapped..” 错误,请参阅(我的回答)this post

        【讨论】:

          【解决方案5】:

          当我尝试在通过主键连接的两个表之间进行一对一操作时,我收到了同样的错误。 (不,我没有设计数据库)。所以,删除FK的解决方案是行不通的——FK也是PK,所以你不打算删除它。作为一个实验,我将关联的一侧更改为 0..1,你瞧,模型编译时没有错误。我使用的是 EF3.5

          【讨论】:

            【解决方案6】:

            简单来说,我做了以下事情:

            1. 在列上使用主键 (PK) 创建表。
            2. 在列上使用外键 (FK) 创建视图。 反之亦然。
            3. 在 edmx 图表设计器中,创建了一个关联。
            4. 编译代码。

            在 XAML 元数据代码中,具有 PK 的父实体将显示子视图实体,可以关联以绑定项目。

            【讨论】:

              【解决方案7】:

              经过差不多一整天的努力,我想通了!事实上,假设我遇到了与 Craig 相同的问题,我找到了 2 种不同的方法来解决这个问题。

              首先,driAn 的回答并没有真正帮助(再一次,如果 Craig 有同样的问题),因为问题是表 A 中没有单独的外键。表 A 的主键完全相同表 B 的主键!特别是在我的情况下,我使用的是一个视图和一个表,而不是两个表:

              table A
              -------
              A_ID int
              col1 int
              col2 int
              
              view A_extra
              -------
              A_ID int
              col3 int
              

              所以,这是我找到的解决方案:

              1.映射到两个不同的实体,但使用 hack。 所以 driAn 的答案的整个问题是我们没有单独的外键列来映射,然后我们可以从属性中删除(我们可以' t 从属性中删除它,因为它是视图 A_extra 的主键!)。因此,一旦您意识到这一点,黑客就会非常简单:编辑 A_extra 并简单地创建 A_ID 的副本并将其设置为备用外键:

              table A
              -------
              A_ID int
              col1 int
              col2 int
              
              view A_extra
              -------
              A_ID int
              A_FK_ID int        
              col3 int
              

              A_FK_ID 在视图的 SQL 中被简单地定义为“A_ID as A_FK_ID”,并且它始终具有与 A_ID 完全相同的值。

              现在,对于实体框架来说,这是一个非常熟悉的场景。只需创建 1 对 1 关联,将关联映射到 A_extra,并将表 A 中的属性 A_ID 映射到 A_FK_ID,将 A_extra 中的属性 A_ID 映射到 A_ID。现在,您不再根据 EF 让同一列执行双重任务!不过,有趣的是,当然,A_FK_ID 总是与 A_extra 中的 A_ID 相同。

              现在您有了 A_extra 的导航属性,并且 col3 可以访问,正如您所期望的那样。更好的是,您仍然可以本地更新 table_A,因为 EF 认为它是一个表(如果您从该组合中创建了一个视图并将其导入 EF,则无法本地更新它)。

              2。将表和视图映射到单个实体。您不需要破解此解决方案,而且最好使用它,因为您不必通过导航属性即可到达 col3。

              要获得此配置,请将 A 和 A_extra 添加到 EF。将 col3 从 A_extra 复制并粘贴到 A 中,这样您现在在 A 中拥有未映射的属性“col3”,而在 A_extra 中没有任何内容。现在转到 A 的映射并将 A_extra 添加为要映射到的视图(以便实体“A”现在映射到表“A”和视图“A_extra”)。将属性 col3(在实体 A 中)映射到列 col3(在视图 A_extra 中)。 现在,您将向 EF 展示如何将两者连接起来以创建单个实体: 将 A_extra 中的 A_ID 列映射到实体 A 中的属性 ID。如果您注意到,您现在有两列映射到相同的属性。没关系,因为它们代表相同的事物,并且正是 EF 知道加入该列的方式。

              现在,要完成清理工作,您必须在设计器中删除浮动实体“A_extra”。 (您可能希望确保它不再映射到视图 A_extra 只是为了确保它也不会带走 A_extra 的商店映射——我希望它不会因为实体 A 现在映射到它)。现在您应该能够从实体 A 构建和访问 col1、col2 和 col3!

              很酷的是,您可以将数据更新到 col1 和 col2,因为它们已映射到表 (A),但 EF 会阻止您更新 col3,因为它已映射到视图 (A_extra) .这比在数据库中使 A 成为组合视图并导入它更方便,因为 EF 会阻止您更新 any 列,因为就它而言,它们都来自一个视图。 p>

              哇,我很高兴我终于让这个工作了。希望我的解决方案对你们有所帮助!

              -罗伯特

              【讨论】:

                【解决方案8】:

                首先在数据库中创建一个外键,然后从数据库中创建关联或更新模型。

                【讨论】:

                  【解决方案9】:

                  不知道答案,但使用 Entity Framework,我总是在每个表中创建一个主键(即使我不需要它)。示例:

                  • 表 Customer 将 CustomerID 作为主键
                  • 表产品以 ProductID 作为主键
                  • Table Order 当然使用 CustomerID + ProductID 作为主键。好吧,我还创建了一个本地主键:OrderID。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-11-11
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多