Контекст данных Entity Framework не содержит коллекции моей сущности, которая использует наследование. Почему?

#c# #entity-framework #inheritance #entity-framework-4 #model

#c# #сущность-фреймворк #наследование #entity-framework-4 #Модель #entity-framework

Вопрос:

Я использую модель с Entity Framework, которая использует преимущества наследования. У меня есть одна сущность для базового типа, называемая «User», и две сущности, которые наследуются от нее («Admin» и «Worker»). Вот модель:


(источник:codetunnel.com )

Проблема в том, что когда я создаю свой контейнер Entity Framework, в нем нет набора работников или администраторов, только пользователи.

 EntityContainer context = new EntityContainer();
context.Users; // Exists.
context.Workers; // does not exist.
  

Как я могу получить коллекцию работников / администраторов, а не только обычных пользователей?
Аналогично, как я могу предоставить моей FamilyAccount сущности свойство навигации для администраторов и работников, а не для обычных пользователей?

Заранее спасибо!

PS — Я использую модель table-per-type для своего наследования, если это имеет значение.

.OfType кажется, работает хорошо. Есть ли другой способ добавить свойство навигации только для работников или администраторов?

Ответ №1:

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

 var admins = context.Users.OfType<Admin>();
var workers = context.Users.OfType<Worker>();
  

Ответ №2:

http://mosesofegypt.net/post/Inheritance-and-Associations-with-Entity-Framework-Part-3.aspx

В этой статье описывается, как расширить сущность и добавить свойство навигации самостоятельно. Перейдите к заголовку «Запрос для конкретного отдела». Это то, чего я добивался, устраняя требование использования .OfType<Worker>() .

Теперь я могу делать familyAccount.Admins , и все хорошо по соседству.

Комментарии:

1. Я не критикую, но что происходит, когда вы нажимаете ОБНОВИТЬ в своей модели? Ваша ручная ассоциация исчезает или она сохраняется?

Ответ №3:

Наследование по таблице для каждого типа (TPT) предполагает хранение всех свойств базового типа в одной таблице. Наследование по таблице для конкретного типа (TPC) предполагает хранение данных для каждого типа в совершенно отдельной таблице без ограничений внешнего ключа между ними.

Если вы хотите отдельные таблицы для администраторов и рабочих, то вам, вероятно, следует использовать TPC.

Комментарии:

1. Нет, TPT предполагает хранение всех типов в отдельных таблицах. Хранение всех в одной таблице называется иерархией для каждой таблицы . Я использую TPT, и они уже являются отдельными таблицами. Пользователи, администраторы и рабочие имеют свои собственные таблицы. TPC — это пограничный случай и полностью отличается от моих потребностей.

2. Нет, TPT хранит все общие элементы данных в одной таблице. Затем все уникальные элементы данных помещаются в соответствующие таблицы классов. TPH помещает ВСЕ элементы данных в одну таблицу и использует дискриминаторы, чтобы определить, к какому подклассу она относится.

3. Правильно, это то, что я только что сказал. TPC — это не то, что мне здесь нужно, поскольку оно используется, когда есть перекрывающиеся поля, которых у меня нет. Я предоставил вам ссылки на статьи, описывающие каждую из них, если у вас есть какая-то информация, которая опровергает предоставленную мной информацию, пожалуйста, свяжите меня с ней.

4. Итак, вы хотите, чтобы структура вашей таблицы оставалась прежней, но вы хотите иметь возможность доступа к списку подклассов непосредственно из контекста?

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