实体框架神奇地将下面的表结构解释为多对多关系。
table foo (int id)
table foo_bar (int foo_id, int bar_id)
table bar (int id)
但是如果连接表有任何其他字段,它将被解释为两个一对多关系。
我正在使用一个数据库,其中连接表有一个代理键作为主键。因此,EF将其解释为两个一对多的关系。
table foo (int id)
table foo_bar (int surrogate_pk, int foo_id, int bar_id)
table bar (int id)
是否可以修改EF:s解释,使其成为模型中实际的多对多关系?可以使用设计师完成吗?
答案 0 :(得分:2)
这是可能的,但它在EDMX文件中需要相当多的手动工作,并且我无法使EF使用代理键作为链接表上的实际主键。您必须使EF使用foo_id和bar_id的组合键作为主键。
在您的存储模型中,您必须从
更改链接表的EntityType<EntityType Name="foo_bar">
<Key>
<PropertyRef Name="surrogate_pk" />
</Key>
<Property Name="surrogate_pk" Type="bigint" Nullable="false" StoreGeneratedPattern="Identity" />
<Property Name="foo_id" Type="int" Nullable="false" StoreGeneratedPattern="None" />
<Property Name="bar_id" Type="int" Nullable="false" StoreGeneratedPattern="None" />
</EntityType>
为:
<EntityType Name="foo_bar">
<Key>
<PropertyRef Name="foo_id" />
<PropertyRef Name="bar_id" />
</Key>
<Property Name="foo_id" Type="int" Nullable="false" StoreGeneratedPattern="None" />
<Property Name="bar_id" Type="int" Nullable="false" StoreGeneratedPattern="None" />
</EntityType>
因此,您要使代理键对EF不可见,并告诉它使用两个外键的组合作为主键。
在概念模型中,您需要定义多个关联:
<Association Name="foo_bar_association">
<End Role="foo" Type="foo" Multiplicity="*" />
<End Role="bar" Type="bar" Multiplicity="*" />
</Association>
在你的映射中,一个AssociationSetMapping:
<AssociationSetMapping Name="foo_bar_association" TypeName="foo_bar_association" StoreEntitySet="foo_bar">
<EndProperty Name="foo">
<ScalarProperty Name="id" ColumnName="foo_id" />
</EndProperty>
<EndProperty Name="bar">
<ScalarProperty Name="id" ColumnName="bar_id" />
</EndProperty>
</AssociationSetMapping>
到目前为止,最简单的方法是从数据库中删除代理键,生成EDMX,然后将此模型放在原始数据库上。结果将是相同的。 EF并不真正需要任何代理键,该表在多对多关联中是不可见的
答案 1 :(得分:1)
我很肯定使用设计师无法做到这一点。我不知道是否有办法在EDMX中手动完成,但我从未见过它的一个例子。一种可能的解决方法可能是根本不映射代理键。如果您可以在数据库中生成它,则可能在模型中不需要它。