Entity Framework 4 Таблица на иерархию - Как определить навигационные свойства для дочерних элементов? - PullRequest
10 голосов
/ 24 ноября 2010

В настоящее время у меня есть модель Entity Framework 4.0 с таблицей на тип (TPT), но есть несколько проблем с производительностью (много операторов LOJ / CASE), а также сопоставление проблем между двумя конкретными областями домена (многие-в-многим).

Я решил попробовать TPH.

У меня есть объект с именем " Location ", который abstract и база для всех других объектов.

У меня тогда есть " Страна ", " Город ", " Штат ", " Street"и т. Д., Которые все происходят из Location.

" LocationType"- это dicriminator .

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

Например, " State " имеет один " Country ",поэтому я должен быть в состоянии сделать это:

var state = _ctx.Locations.OfType<State>().Include("Country").First();
var countryForState = state.Country;

Но для этого потребуется навигационное свойство "Страна" в производном объекте "Состояние".Как мне это сделать?Когда я генерирую модель из базы данных, у меня есть одна таблица со всеми FK, указывающими на записи в одной и той же таблице:

alt text

(ПРИМЕЧАНИЕ. Я создал эти FK вручную вDB).

Но FK помещаются в виде nav на сущность " Location ", так как я могу переместить эти навигационные свойства вниз к производным сущностям?Я не могу скопировать + вставить навигационные элементы, и я не могу «создать новое навигационное свойство», потому что оно не позволит мне определить начальную / конечную роль.

Как нам это сделать?

С TPH также неясно, можем ли мы сделать это сначала на модели, или мы ДОЛЖНЫ начать с БД, исправить модель, а затем заново сгенерировать БД.Мне еще предстоит найти хороший пример в Интернете о том, как определить навигацию для детей с TPH.

ПРИМЕЧАНИЕ: Я не хочу делать сначала код .Мое текущее решение имеет TPT с EDMX и чистые POCO, я надеюсь не повлиять на модель / репозитории домена (если возможно), а просто обновить модель / базу данных EF.

EDIT

По-прежнему нет решения - однако я пытаюсь сделать сначала модель, и делаю Add -> New Association, что фактически позволяет мне добавить навигацию к производным сущностям.Но когда я пытаюсь «Сгенерировать базу данных из модели», он все еще пытается создать таблицы для «Location_Street», «Location_Country» и т. Д. Это почти как TPH не может быть сделано в первую очередь моделью.

EDIT

Вот моя текущая модель:

alt text

Ошибка проверки, которую я сейчас получаю:

Ошибка 1 Ошибка 3002:Проблема при отображении фрагментов, начинающихся со строки 359. Потенциальное нарушение во время выполнения таблицы Ключи Locations (Locations.LocationId): Столбцы (Locations.LocationId) сопоставляются со свойствами EntitySet NeighbourhoodZipCode (NeighbourhoodZipCode.Neighbourhood.LocationId), но не имеют концептуальной стороны.ключевые свойства EntitySet (NeighbourhoodZipCode.Neighbourhood.LocationId, NeighbourhoodZipCode.ZipCode.LocationId).

Просто подумал, что продолжу редактировать этот вопрос с правками относительно того, где я сейчас нахожусь.Я начинаю задаваться вопросом, возможна ли даже ТПХ с самоссылающимися ФК.

РЕДАКТИРОВАТЬ

Итак, я выяснил вышеупомянутую ошибку, потому что я пропалтаблица соединения для Neighborhood-ZipCode многие ко многим.

Добавление таблицы соединения (и сопоставление навигационных данных с этим) решило вышеуказанную ошибку.

Но теперь я получаю эту ошибку:

Ошибка 3032: проблема в отображении фрагментов, начинающихся со строк 373, 382: члены условия Locations.StateLocationId имеют дублированные значения условий.

Если я смотрю наCSDL, вот сопоставление ассоциации для "CountyState" (штат имеет много округов, округ имеет 1 штат):

<AssociationSetMapping Name="CountyState" TypeName="Locations.CountyState" StoreEntitySet="Locations">
   <EndProperty Name="State">
      <ScalarProperty Name="LocationId" ColumnName="StateLocationId" />
   </EndProperty>
   <EndProperty Name="County">
      <ScalarProperty Name="LocationId" ColumnName="LocationId" />
   </EndProperty>
   <Condition ColumnName="StateLocationId" IsNull="false" />
</AssociationSetMapping>

Это тот самый Condition ColumnName="StateLocationId", который жалуется, потому что ZipCodeState ассоциация также этосостояние.

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

  1. В округе имеется один штат, обозначаемый StateLocationId (таблица местоположений)
  2. ZipCode имеет одно состояние, обозначаемое StateLocationId (таблица расположений)

Разве это не действует в TPH?

1 Ответ

5 голосов
/ 26 ноября 2010

Итак, я решил несколько своих проблем, но наткнулся на кирпичную стену.

Прежде всего, когда вы создаете FK, ссылающиеся на себя, на стороне базы данных, когда вы пытаетесь «Обновить модель из базы данных»."Entity Framework добавит эти навигационные свойства к основному базовому типу, так как он не имеет явного смысла в TPH - вам нужно сделать это на стороне модели.

НО, вы можете вручную добавить навигационные свойства вдочерние типы.

WRT эта ошибка:

Ошибка 3032: проблема при отображении фрагментов, начинающихся со строк 373, 382: члены условия 'Locations.StateLocationId' имеют повторяющиеся значения условия.

Это было из-за того, что у меня был FK с именем Location_State, который я пытался использовать для отношения "ZipCode_State", И отношения "City_State" - который не работает (до сих пор не знаю, почему).

Итак, чтобы решить эту проблему, мне пришлось добавить дополнительные столбцы и дополнительные FK - один с именем "ZipCode_State", а другой с именем "City_State" - очевидно, он имеетбыть 1-1 между навигацией и физическим FK.

Location.LocationType не имеет значения по умолчанию и не может иметь значение NULL.Значение столбца требуется для хранения данных объекта.

Это мое поле дискриминатора.Что касается базы данных, это не обнуляется .

Я читал темы об этой проблеме, и они сказали, что вам нужно изменить отношения с 0 .. * до 1 .. * - номои отношения уже были 1 .. *.

Если вы посмотрите на мою фактическую таблицу базы данных "Локации" выше, все FK обнуляются (они должны быть).Поэтому я начал задаваться вопросом, должны ли мои отношения быть 0 .. *.

Но они обнуляются из-за TPH - не все "Местоположения" будут иметь "Состояние".Но если это местоположение является «городом», то оно ДОЛЖНО иметь «государство».

Мои чувства были еще более утешены этим SO вопросом: ADO EF - сопоставление ошибок между производными типами в TPH

Я на самом деле пробовал этот обходной путь (прежде чем я даже столкнулся с ним), и обходной путь не работает для меня.Я даже попытался изменить все отношения с 1 .. * до 0 .. *, но все равно не повезло.

Потратив слишком много времени здесь, я вернулся к TPT.

Вв конце дня с TPH у меня была бы смехотворно большая таблица с множеством избыточных, обнуляемых столбцов.СОВМЕСТНО, это более эффективно.Но по крайней мере с TPT я не обязан иметь обнуляемые и самоссылающиеся FK.

Если у кого-то есть решение этой проблемы, дайте мне знать.Но до тех пор, я придерживаюсь TPT.

...