Подтвердить что ты не робот

Определение ассоциации 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>

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

4b9b3361

Ответ 1

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

Пример:

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


table B
-------
B_ID int

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

Ответ 2

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

Ответ 3

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

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

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

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

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

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

: - Dan

Ответ 4

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

Ответ 5

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

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

Если после этого вы получите сообщение об ошибке "Ассоциация не отображается.", см. (мой ответ) этот пост.

Ответ 6

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

Ответ 7

Простыми словами я сделал следующее:

  • Создать таблицу с основным ключом (PK) в столбце.
  • Создайте представление с помощью внешнего ключа (FK) в столбце. или наоборот.
  • В edmx Diagram Designer создана Ассоциация.
  • Скомпилируйте код.

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

Ответ 8

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

Во-первых, ответ driAn действительно не помогает (еще раз, если у Крейга есть такая же проблема, как и у меня), поскольку проблема в том, что в таблице нет отдельного внешнего ключа. Таблица. Первичный ключ - это то же самое первичный ключ для таблицы 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 как A_FK_ID" в представлении SQL, и всегда будет иметь то же значение, что и A_ID.

Теперь, для структуры сущностей, это очень знакомый сценарий. Просто создайте ассоциацию 1-to-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 доступен, как и следовало ожидать. Еще лучше, вы все еще можете изначально обновить таблицу_A, так как EF видит, что это таблица (если вы сделали один вид из этой комбинации и импортировали ее в EF, вы не можете ее обновить).

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

Чтобы получить эту конфигурацию, добавьте A и A_extra в EF. Скопируйте и вставьте col3 из A_extra в A, так что теперь у вас есть unmapped свойство "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), Это более удобно, чем сделать A объединенным представлением в БД и импортировать его, потому что EF не позволит вам обновлять какие-либо столбцы, поскольку они все из представления, насколько это касается.

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

-Роберт

Ответ 9

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

  • Клиент таблицы имеет CustumerID как первичный ключ
  • Продукт таблицы имеет ProductID как первичный ключ.
  • Таблица. В качестве первичного ключа, конечно, используйте CustomerID + ProductID. Ну, я также создаю один локальный первичный ключ: OrderID.