В настоящее время у меня есть модель Entity Framework 4.0 с Table Per Type (TPT), но есть несколько проблем с производительностью (много операторов LOJ/CASE), а также сопоставление проблем между двумя конкретными доменами (многие -в-многим).
Я решил попробовать TPH.
У меня есть объект, называемый Местоположение ", который является абстрактным, и базой для всех других объектов.
Затем у меня есть Страна "," Город "," Состояние "," Улица ", и т.д., которые все происходят из Местоположение.
" LocationType" является dicriminator.
Эта часть работает нормально, но у меня возникают проблемы с определением навигационных свойств для производных типов.
Например, " State" имеет единственную " Страну", поэтому я должен иметь возможность сделать это:
var state = _ctx.Locations.OfType<State>().Include("Country").First();
var countryForState = state.Country;
Но для этого должно существовать навигационное свойство, называемое "Страна", на основе "State". Как мне это сделать? Когда я создаю модель из базы данных, у меня есть одна таблица со всеми FK, указывающими на записи в той же таблице:
(ПРИМЕЧАНИЕ: я создал эти FK вручную в БД).
Но FK помещаются как nav в объект Местоположение, так как я могу перенести эти навигационные свойства на производные объекты? Я не могу скопировать + вставить навигаторы, и я не могу "создать новое навигационное свойство", потому что он не позволит мне определить начальную/конечную роль.
Как мы это делаем?
Также неясно, с TPH, если мы сможем сделать это во-первых, или мы должны начать с БД, исправить модель, а затем повторно сгенерировать БД. Мне еще предстоит найти хороший пример в Интернете о том, как определить navs для детей с TPH.
ПРИМЕЧАНИЕ. Я не хочу делать код сначала. Мое текущее решение имеет TPT с EDMX и чистые POCO, я надеюсь не влиять на модель/репозитории домена (если это возможно) и просто обновлять модель/базу данных EF.
ИЗМЕНИТЬ
По-прежнему нет решения - однако я пытаюсь сделать сначала модель, а Add → New Association, что на самом деле позволяет мне добавить навигацию к производным объектам. Но когда я пытаюсь "Генерировать базу данных из модели", она по-прежнему пытается создать таблицы для "Location_Street", "Location_Country" и т.д. Это почти так же, как TPH не может быть сначала выполнена.
ИЗМЕНИТЬ
Вот моя текущая модель:
Ошибка проверки, которую я получаю:
Ошибка 1 Ошибка 3002: проблема при сопоставлении фрагменты, начинающиеся с линии 359: Потенциальное нарушение времени выполнения таблицы (Locations.LocationId): столбцы (Locations.LocationId) отображаются на EntitySet NeighbourhoodZipCode's свойства (NeighbourhoodZipCode.Neighbourhood.LocationId) на концептуальной стороне, но они не сформировать свойства ключа EntitySet (NeighbourhoodZipCode.Neighbourhood.LocationId, NeighbourhoodZipCode.ZipCode.LocationId).
Просто подумал, что я продолжу редактирование этого вопроса с правлением относительно того, где я сейчас. Я начинаю задаваться вопросом, возможна ли TPH с саморегуляцией FK.
ИЗМЕНИТЬ
Итак, я выяснил вышеприведенную ошибку, потому что мне не хватало таблицы соединений для 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
также связывает это условие.
Но я не понимаю. Дискриминаторы для всех объектов уникальны (я проверял тройку), и я бы подумал, что это допустимый сценарий:
- У округа есть одно состояние, обозначенное командой StateLocationId (Таблица мест)
- ZipCode имеет одно состояние, обозначенное как StateLocationId (Таблица мест)
Это неверно в TPH?