与实体框架中的代理键的多对多关系

时间:2009-02-16 20:26:25

标签: entity-framework many-to-many surrogate-key

实体框架神奇地将下面的表结构解释为多对多关系。

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解释,使其成为模型中实际的多对多关系?可以使用设计师完成吗?

2 个答案:

答案 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中手动完成,但我从未见过它的一个例子。一种可能的解决方法可能是根本不映射代理键。如果您可以在数据库中生成它,则可能在模型中不需要它。