代码之家  ›  专栏  ›  技术社区  ›  Craig Fisher

定义实体框架1:1关联

  •  12
  • Craig Fisher  · 技术社区  · 17 年前

    我尝试在实体框架模型中定义两个实体(一个映射到表,另一个映射到视图——使用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的一部分指定的列“DOCUMENT”在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>
    

    我没有得到什么?

    9 回复  |  直到 12 年前
        1
  •  6
  •   driAn    17 年前

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

    例子:

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

    在本例中,您将在设计器中选择表A,因为它包含外键。此外,您还需要从A实体中删除B_ID。

        2
  •  0
  •   mike mike    17 年前

    我正在处理一个旧的应用程序,所以添加一个额外的主键对我来说不是一个选择。我要做的是将其映射为1:(0或1),而不是1:1,以使其工作。例如,如果我有两个表,那么Customer和CustomerDetails都有一个主键CustomerID。为了创建关联,我必须将其设置为1 Customer can related To(0或1)CustomerDetails记录。每次插入客户时,请确保同时插入客户详细信息,以便可以保持1:1。

        3
  •  0
  •   Watki02    16 年前

    我同意这种设置方式似乎有违直觉。对于那些太慢(像我这样)得不到德里安答案的人: 根据下面的论坛帖子,我记得我们是在处理一个实体,而不是一个表格。协会在

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

    实体框架正在关联 属性 表列 . 所以我们必须删除“外键” 财产 实体 (注意:我们不会删除表列)。引用代码中的列,(使用 实体 建模 表A和表B)的给定示例如下:

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

    第二个赋值是使用实体中定义的关联来获取数据。没有 财产

    这一切都是假设我理解正确的:)。至少现在我的理解是正确的。

    :-丹

        4
  •  0
  •   Community Mohan Dere    9 年前

    概念设计中不应该有外键。 我相信这在EF4中是允许的(只是做了一些调整),但是在EF3.5中,这是做不到的。

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

    如果你得到一个 “关联结束未映射..” this post .

        5
  •  0
  •   Antony    15 年前

        6
  •  0
  •   Pankaj Awasthi    15 年前

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

    1. 在列上创建主键(PK)的表。
    2. 在列上创建具有外键(FK)的视图。 反之亦然。
    3. 在edmx图表设计器中,创建了一个关联。

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

        7
  •  0
  •   JoeCool    14 年前

    首先,driAn的答案并没有真正的帮助(再一次,如果Craig也有同样的问题),因为问题是表A中没有单独的外键。表A的主键与表B的主键完全相同!具体来说,我使用的是一个视图和一个表,而不是两个表:

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

    因此,我找到了以下解决方案:

    1映射到两个不同的实体,但使用黑客。 所以,driAn的答案的全部问题是我们没有一个单独的外键列来映射,我们可以从属性中删除它(我们不能从属性中删除它,因为它是视图的主键)。因此,一旦你意识到了,破解就变得异常简单:编辑一个“多余”并简单地创建一个_ID的副本,并将其作为备用外键:

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

    现在,对于实体框架来说,这是一个非常熟悉的场景。只需创建1对1的关联,将关联映射到一个\u extra,并将表A中的属性A_ID映射到一个_FK_ID,将一个_extra中的属性A_ID映射到一个_ID。现在您不再需要根据EF使同一列执行双重任务!然而,有趣的是,一个_-FK_-ID总是和一个_-extra中的一样。

    现在您有了一个指向一个额外的导航属性,col3可以访问,正如您所期望的那样。更好的是,您仍然可以在本机更新table_A,因为EF认为它是一个表(如果您从这个组合中创建了一个视图并将其导入到EF中,则不能以本机方式更新它)。

    这个解决方案不需要黑客攻击,而且它更可取,因为您不必通过导航属性就可以到达col3。

    下面是如何向EF展示如何将两者结合起来创建单个实体: 将A_extra中的列A_ID映射到实体A中的属性ID。如果您注意到,现在有两个列映射到同一个属性。这没关系,因为它们代表相同的东西,而且正是EF知道如何连接到该列上的。

    最酷的是,可以很好地将数据更新到col1和col2,因为它们映射到表(a),但是EF会阻止您更新col3,因为它映射到一个视图(一个额外的)。这比在数据库中创建一个组合视图并导入它更方便,因为EF会阻止您更新 任何

    哇,我真高兴我终于成功了。希望我的解决方案对你们有帮助!

    -罗伯特

        8
  •  0
  •   Echilon Mafarnakus    13 年前

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

        9
  •  -3
  •   Sylvain Rodrigue    17 年前

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

    • 表Product的主键是ProductID
    • 表顺序当然使用CustomerID+ProductID作为主键。我还创建了一个本地主键:OrderID。