Определение ассоциации Entity Framework 1: 1

Я пытаюсь определить связь 1: 1 между двумя объектами (одна отображается в таблице, а другая - в представлении - с помощью DefinedQuery) в модели Entity Framework. Когда я пытаюсь определить сопоставление для этого в дизайнере, я выбираю (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, не существует в 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>

Что я не получаю?


person Craig Fisher    schedule 24.01.2009    source источник
comment
Есть ли способ повторно опубликовать это изображение? У меня такая же проблема, но я не уверен, что наши дизайны одинаковы.   -  person Shawn Mclean    schedule 08.04.2010


Ответы (9)


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

Пример:

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


table B
-------
B_ID int

В этом случае вы должны выбрать в дизайнере таблицу A, поскольку она содержит внешний ключ. Также вам нужно будет впоследствии удалить B_ID из объекта A.

person driAn    schedule 24.01.2009

Я имел дело с устаревшим приложением, поэтому добавление дополнительного первичного ключа не было для меня вариантом. Что мне нужно было сделать, так это отобразить его как 1: (0 или 1), а не как 1: 1, чтобы заставить его работать. Например, если бы у меня было две таблицы, скажем, Customer и CustomerDetails, у обеих был первичный ключ с именем CustomerID. Чтобы создать ассоциацию, мне пришлось настроить ее, так как 1 Customer может относиться к (0 или 1) записям CustomerDetails. Каждый раз, когда вы вставляете клиента, не забудьте также вставить CustomerDetails, чтобы вы могли поддерживать соотношение 1: 1.

person Community    schedule 16.09.2009

Я согласен с тем, что это кажется нелогичным. Для тех, кто слишком медлителен (например, я), чтобы получить ответ DriAn: в сообщении на форуме ниже я вспомнил, что мы имеем дело с сущностью, а не с таблицей напрямую. Связь связана с объектом (который может моделировать таблицу, но не обязательно).

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

Структура сущности связывает СВОЙСТВА с СТОЛБЦЫ ТАБЛИЦ. Вот почему мы должны удалить «внешний ключ» PROPERTY на ENTITY (примечание: мы не удаляем столбец таблицы). Чтобы сослаться на столбец в коде (используя ENTITY моделирование данного примера ТАБЛИЦ А и ТАБЛИЦЫ B), вы должны написать что-то вроде этого:

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

Второе назначение использует ассоциацию, определенную в сущности, для доступа к данным. В таблице A нет СВОЙСТВА с именем "B_ID".

Это все, если я правильно понимаю :). По крайней мере, сейчас для меня это правильно.

: -Дэн

person Watki02    schedule 07.12.2009

В Entity Framework в концептуальном дизайне не должно быть внешних ключей. Я считаю, что теперь это разрешено в EF4 (с некоторыми настройками), но в EF3.5 это невозможно.

Чтобы исправить это, просто удалите все свойства, представляющие внешние ключи в EF-конструкторе. Не удаляйте первичные ключи!

Если затем вы получите сообщение об ошибке «Конец ассоциации не сопоставлен ..», см. (Мой ответ на) этот пост.

person BlueRaja - Danny Pflughoeft    schedule 05.05.2010

Я получил ту же ошибку, когда попытался выполнить взаимно однозначное соответствие между двумя таблицами, соединенными по их первичным ключам. (Нет, я не проектировал БД). Итак, решение по удалению FK не работает - FK также является PK, поэтому вы не собираетесь его удалять. В качестве эксперимента я изменил одну сторону ассоциации на 0..1, и о чудо, модель скомпилирована без ошибок. Я использовал EF3.5

person Antony    schedule 09.12.2010

Проще говоря, я сделал следующее:

  1. Создайте таблицу с первичным ключом (PK) в столбце.
  2. Создайте представление с внешним ключом (FK) для столбца. или наоборот.
  3. В edmx Diagram Designer создал Association.
  4. Скомпилируйте код.

В коде метаданных XAML родительская сущность, имеющая PK, будет отображать дочернюю сущность представления, которую можно связать для привязки элементов.

person Pankaj Awasthi    schedule 06.07.2011

После целого дня работы над этим я понял это! Фактически, я нашел 2 разных способа решения этой проблемы, если предположить, что у меня была та же проблема, что и у Крейга.

Во-первых, ответ driAn на самом деле не помогает (еще раз, если у Крейга такая же проблема, как и у меня), поскольку проблема в том, что в таблице A нет отдельного внешнего ключа. Первичный ключ таблицы A является точно таким же первичным ключом для Таблица B! В частности, в моем случае я использую представление и таблицу, а не две таблицы:

table A
-------
A_ID int
col1 int
col2 int

view A_extra
-------
A_ID int
col3 int

Итак, вот решения, которые я нашел:

1. Сопоставьте с двумя разными объектами, но используйте хитрость. Итак, вся проблема с ответом driAn заключается в том, что у нас нет отдельного столбца внешнего ключа для сопоставления, который мы затем можем удалить из свойств (мы можем ' t удалите его из свойств, потому что это первичный ключ представления A_extra!). Таким образом, взлом становится безумно простым, как только вы это понимаете: отредактируйте A_extra и просто создайте копию A_ID и сделайте ее замещающим внешним ключом:

table A
-------
A_ID int
col1 int
col2 int

view A_extra
-------
A_ID int
A_FK_ID int        
col3 int

A_FK_ID просто определяется как «A_ID as A_FK_ID» в SQL представления, и он всегда будет иметь то же самое значение, что и A_ID.

Что касается структуры сущностей, это очень знакомый сценарий. Просто создайте ассоциацию «1 к 1», сопоставьте ассоциацию с A_extra и сопоставьте свойство A_ID в таблице A с A_FK_ID и свойство A_ID в A_extra с A_ID. Теперь вы больше не заставляете одну и ту же колонну выполнять двойную функцию согласно EF! Однако забавно то, что A_FK_ID всегда будет идентичен A_ID в A_extra.

Теперь у вас есть свойство навигации для A_extra, и col3 доступен, как и следовало ожидать. Более того, вы все равно можете обновить table_A изначально, поскольку EF видит, что это таблица (если вы создали одно представление из этой комбинации и импортировали его в EF, вы не можете обновить его изначально).

2. Сопоставьте таблицу и представление с одной сущностью. Для этого решения не требуется взлома, и это предпочтительнее, потому что вам не нужно проходить через свойство навигации, чтобы перейти к col3.

Чтобы получить эту конфигурацию, добавьте в EF как A, так и A_extra. Скопируйте и вставьте col3 из A_extra в A, так что теперь у вас есть несопоставленное свойство col3, сидящее в A, и ничего в A_extra. Теперь перейдите к отображению для A и добавьте A_extra в качестве представления, которое будет отображено (так, чтобы объект «A» теперь отображался как на таблицу «A», так и на представление «A_extra»). Сопоставьте свойство col3 (в сущности A) со столбцом col3 (в представлении A_extra). Теперь вот как вы показываете EF, как объединить эти два для создания единой сущности: сопоставьте столбец A_ID в A_extra с идентификатором свойства в сущности A. Если вы заметили, теперь у вас есть ДВА столбца, сопоставленные с такое же свойство. Это нормально, поскольку они представляют одно и то же, и именно так EF знает, что нужно присоединиться к этому столбцу.

Теперь, чтобы закончить очистку, вам нужно удалить плавающий объект «A_extra» в дизайнере. (Возможно, вы захотите убедиться, что он больше не отображается для просмотра A_extra, просто чтобы убедиться, что он также не отменяет отображение хранилища для A_extra - я бы надеялся, что это не так, поскольку объект A теперь сопоставлен с ним). Теперь у вас должна быть возможность создавать и получать доступ ко всем столбцам col1, col2 и col3 из объекта A!

Замечательно то, что вы можете обновлять данные до col1 и col2 в порядке, поскольку они сопоставлены с таблицей (A), но EF не позволит вам, как следует, обновить col3, поскольку он сопоставлен с представлением (A_extra). Это удобнее, чем создание комбинированного представления в базе данных и его импорт, поскольку EF не позволит вам обновлять любые столбцы, поскольку все они находятся в представлении, насколько это возможно.

Уф, я так рад, что наконец-то это заработало. Надеюсь, мои решения помогли вам, ребята!

-Роберт

person JoeCool    schedule 03.07.2012

Сначала создайте внешний ключ в базе данных, а затем создайте модель ассоциации или обновления из базы данных.

person user328691    schedule 29.04.2010

Не уверен, что у меня есть ответ, но с Entity Framework я всегда создаю первичный ключ в каждой таблице (даже если он мне не нужен). Пример :

  • Таблица Customer имеет CustumerID в качестве первичного ключа
  • Таблица Product имеет ProductID в качестве первичного ключа
  • Table Order, конечно, использует CustomerID + ProductID в качестве первичного ключа. Ну, я также создаю единственный локальный первичный ключ: OrderID.
person Sylvain Rodrigue    schedule 26.03.2009