Отношения многие ко многим с суррогатным ключом в Entity Framework - PullRequest
1 голос
/ 16 февраля 2009

Entity Framework волшебным образом интерпретирует следующую структуру таблицы как отношение «многие ко многим».

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, чтобы она стала фактическим отношением "многие ко многим" в модели? Можно ли это сделать с помощью дизайнера?

Ответы [ 2 ]

2 голосов
/ 04 января 2011

это возможно, но это требует немало ручной работы в файле 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 голос
/ 16 февраля 2009

Я уверен, что это не может быть сделано с помощью дизайнера. Я не знаю, есть ли способ сделать это в EDMX вручную, но я никогда не видел пример этого. Одним из возможных решений может быть отсутствие сопоставления суррогатного ключа. Если вы можете сгенерировать это в базе данных, вам может не понадобиться это в вашей модели.

...