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

时间:2022-10-05 15:23:25

Entity Framework magically interprets the following table structure as a many-to-many relationship.

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

table foo (int id)
table foo_bar (int foo_id, int bar_id)
table bar (int id)

But if the join table has any additional fields it will instead be interpreted as two one-to-many relationships.

但是如果连接表有任何其他字段,它将被解释为两个一对多关系。

I am using a database in which the join table has a surrogate key as primary key. Because of this EF interprets it as two one-to-many relationships.

我正在使用一个数据库,其中连接表有一个代理键作为主键。因此,EF将其解释为两个一对多的关系。

table foo (int id)
table foo_bar (int surrogate_pk, int foo_id, int bar_id)
table bar (int id)

Is it possible to modify EF:s interpretation to make it an actual many-to-many relationship in the model? Can it be done using the designer?

是否有可能修改EF:s解释,使其成为模型中实际的多对多关系?可以使用设计师完成吗?

2 个解决方案

#1


I am positive that this cannot be done using the designer. I don't know if there is a way to do it in EDMX manually, but I have never seen an example of it. One possible workaround might be to not map the surrogate key at all. If you can generate that on the database, you might not need it in your model.

我很肯定使用设计师无法做到这一点。我不知道是否有办法在EDMX中手动完成,但我从未见过它的一个例子。一种可能的解决方法可能是根本不映射代理键。如果您可以在数据库上生成它,则可能在模型中不需要它。

#2


it's possible, but it requires quite a bit of manual work in the EDMX file, and I haven't been able to make EF use the surrogate key as actual primary key on the link table. You have to make EF use a combination key of both foo_id and bar_id as primary key.

它是可能的,但它需要EDMX文件中的相当多的手动工作,并且我无法使EF使用代理键作为链接表上的实际主键。您必须使EF使用foo_id和bar_id的组合键作为主键。

in your storage model you have to change the EntityType of the link table from

在您的存储模型中,您必须更改链接表的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>

to:

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

So you make the surrogate key invisible to EF, and tell it to use the combination of the two foreign keys as primary key.

因此,您要使代理键对EF不可见,并告诉它使用两个外键的组合作为主键。

In your conceptual model, you need to have the many-many association defined:

在概念模型中,您需要定义多个关联:

<Association Name="foo_bar_association">
    <End Role="foo" Type="foo" Multiplicity="*" />
    <End Role="bar" Type="bar" Multiplicity="*" />
</Association>

and in your mappings, an AssociationSetMapping:

在你的映射中,一个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>

By far the easiest way to get this right, is to remove the surrogate key from the db, generate the EDMX, and then put this model on your original DB. The result will be the same. EF doesn't really need the surrogate key for anything, the table is invisible in a many-many association

到目前为止,最简单的方法是从数据库中删除代理键,生成EDMX,然后将此模型放在原始数据库上。结果将是相同的。 EF并不真正需要任何代理键,该表在许多关联中是不可见的

#1


I am positive that this cannot be done using the designer. I don't know if there is a way to do it in EDMX manually, but I have never seen an example of it. One possible workaround might be to not map the surrogate key at all. If you can generate that on the database, you might not need it in your model.

我很肯定使用设计师无法做到这一点。我不知道是否有办法在EDMX中手动完成,但我从未见过它的一个例子。一种可能的解决方法可能是根本不映射代理键。如果您可以在数据库上生成它,则可能在模型中不需要它。

#2


it's possible, but it requires quite a bit of manual work in the EDMX file, and I haven't been able to make EF use the surrogate key as actual primary key on the link table. You have to make EF use a combination key of both foo_id and bar_id as primary key.

它是可能的,但它需要EDMX文件中的相当多的手动工作,并且我无法使EF使用代理键作为链接表上的实际主键。您必须使EF使用foo_id和bar_id的组合键作为主键。

in your storage model you have to change the EntityType of the link table from

在您的存储模型中,您必须更改链接表的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>

to:

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

So you make the surrogate key invisible to EF, and tell it to use the combination of the two foreign keys as primary key.

因此,您要使代理键对EF不可见,并告诉它使用两个外键的组合作为主键。

In your conceptual model, you need to have the many-many association defined:

在概念模型中,您需要定义多个关联:

<Association Name="foo_bar_association">
    <End Role="foo" Type="foo" Multiplicity="*" />
    <End Role="bar" Type="bar" Multiplicity="*" />
</Association>

and in your mappings, an AssociationSetMapping:

在你的映射中,一个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>

By far the easiest way to get this right, is to remove the surrogate key from the db, generate the EDMX, and then put this model on your original DB. The result will be the same. EF doesn't really need the surrogate key for anything, the table is invisible in a many-many association

到目前为止,最简单的方法是从数据库中删除代理键,生成EDMX,然后将此模型放在原始数据库上。结果将是相同的。 EF并不真正需要任何代理键,该表在许多关联中是不可见的