#inheritance #entity-framework-4 #table-per-type
#наследование #entity-framework-4 #таблица для каждого типа
Вопрос:
Мне нужно реализовать решение с 1 базовым классом и 3 подклассами (4 класса)
Базовый класс: User
Клиентские подклассы:, OfficeUser, Employee
В моей базе данных у меня есть только 3 таблицы: Пользователи, клиенты и сотрудники.
У меня нет таблицы OfficeUsers, поскольку все необходимые мне данные уже есть в таблице Users.
В будущем я хочу иметь возможность создавать отчеты с перечислением количества клиентов, сотрудников и офисных пользователей.
Я не хочу использовать TPH, поскольку у меня много полей, не обнуляемых в таблице Clients и Employees.
Должен ли я создать таблицу OfficeUsers только с идентификатором пользователя, чтобы я мог реализовать TPT?
Для меня это выглядит как не очень хороший дизайн — наличие таблицы только с PK, чтобы я мог ее правильно отобразить — пожалуйста, поправьте меня, если это способ сделать это.
Другим вариантом было иметь столбец UserType в таблице Users и использовать его в качестве дискриминатора, но будет ли это работать с TPT? Возможно ли создать TPT с 1 отсутствующей таблицей и использовать дискриминаторы, похоже на смешивание TPT и TPH, что, я думаю, невозможно.
Заранее спасибо за ваши ответы.
Редактировать:
Пожалуйста, также рассмотрите этот сценарий:
я представляю новый класс с именем MobileUser
, который также имеет те же поля, что и User
. В этом случае у меня нет способа узнать, сколько MobileUsers
и сколько OfficeUsers
в системе, без введения нового столбца для пользовательского типа.
Наличие в этом сценарии 2 пустых таблиц (только PK) лучше / хуже, чем создание зависимости в моих запросах от количества таблиц и, дополнительно, предотвращение использования некоторых запросов LINQ (пожалуйста, смотрите Мои комментарии под ответом Ладислава Мрнки)
ПРАВКА 2:
Есть вероятность, что в OfficeUser
будущем мне придется добавлять поля, поэтому я начинаю думать, что пустая таблица может быть каким-то вариантом, по крайней мере, код C # (запросы) будет выглядеть чище. Дайте мне знать, если у вас есть лучший подход.
Ответ №1:
Я думаю, что это просто проблема перспективы, а не архитектурная… потому что, что бы вы ни делали, в конечном итоге вы получаете единственную таблицу PK.
Вы можете создать таблицу OfficeUsers, которая может содержать только PK пользователя… просто не делайте это унаследованным типом. Теперь у вас есть список всех пользователей, использующих office, к которому вы можете запросить. Структура точно такая же, но мышление немного отличается.
Если бы у вас было несколько офисов, у вас была бы таблица офисов с идентификатором, тогда у вашего OfficeUser была бы своя таблица типов, поскольку дополнительным полем был бы внешний ключ office… предоставление вам желаемого различия.
Но, поскольку у вас только (я полагаю) один office, вам не нужен внешний ключ, поэтому вам просто нужна одна таблица для хранения пользователей, которые используют office… это «6 из одного, полдюжины из другого», на самом деле абсолютно то же самое, какой бы способ вы ни выбрали.
Вот почему я бы последовал вашему инстинкту во 2-й правке, вы могли бы добавить больше полей позже, так что вы также можете создать «пустой» тип… потому что в любом случае вы получите таблицу, в которой хранятся только PKS.
Ответ №2:
Если ваш OfficeUser
точно такой же, как User
, то вам не нужен никакой дополнительный класс. Используйте User
вместо OfficeUser
и производные классы для Employee
и Client
Комментарии:
1. @ladislav-mrnka Я думал об этом, но тогда я не смогу использовать запросы типа
where user is OfficeUser
илиfrom ou in entities.Users.OfType<OfficeUser>()
. Чтобы узнать количество пользователей OfficeUsers, мне нужно будет получить всех пользователей, где пользователь не является клиентом или сотрудником2. Да, это правда. Вам придется использовать
Where(x => !(x is Employee))
3. @ladislav-mrnka Да, и когда я представлю новую таблицу, такую как
MobileUser
, мне придется модифицировать запросы, чтобы убедиться, что она включает другую таблицу (в данном случае 3 оператора «is not» в предложении where). Как вы думаете, это решение лучше, чем создание пустой таблицы для OfficeUser ?4. Нет, это не лучшее решение, но добавление пустой таблицы также не похоже на решение. Я подумаю об этом.