Entity Framework - абстрактный базовый класс без сопоставления с таблицей DB

У меня есть ситуация, когда у меня есть 4-5 очень похожих классов, которые я бы хотел повторно использовать для использования абстрактного базового класса. Идея этого заключалась в том, чтобы позволить методам, которые могут быть использованы каждым классом при соблюдении принципов СУХОЙ.

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

Какой лучший/рекомендуемый метод, чтобы добавить базовый класс в мою EF-модель и сделать существующие классы в модели наследовать от этого в качестве базы? На данный момент у меня нет проблем с добавлением базового класса, придающего ему свойство идентификатора, которое, как ему кажется, требуется, и затем создание наследования, но EF затем стонет

'Error 3024: Problem in mapping fragments starting at line 18563:Must specify mapping for all key properties (MyBaseType.ID) of the EntitySet MyBaseType.'

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

Любые идеи о том, как добавить в базовый класс таким образом? Или я должен просто добавлять базовый класс в код и как-то обходить модель?

EDIT: В качестве дополнительной информации возьмите пример, в котором говорят 3 типа: MortageApplicationForm, BankAccountApplicationForm и CreditCardApplication. В настоящее время они хранятся в трех разных таблицах с набором различных полей. То, что я пытаюсь сделать, - создать базовый класс, который называется "Форма", который будет иметь общие поля в нем.

На простом уровне скажите, что каждая таблица имеет поле идентификатора первичного ключа, называемое "CreditCardFormID", "BankAccountFormID" и т.д. Что бы я хотел сделать, это создать базовый класс "Form" с идентификатором свойства, который для случая из одной таблицы будет отображаться "CreditCardFormID" и другой "BankAccountFormID".

Я рад сделать это сопоставление в частичных классах (поскольку я не хочу сохранять идентификатор в БД), я просто хочу использовать его в коде, поэтому я могу писать общие методы для таких вещей, как LoadForm (int ID) без необходимости писать огромные переключатели для каждого типа сущности или конкретные методы для каждого типа сущности.

Ответ 1

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

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

Это было связано с интерфейсом "IAccount", позволяющим вспомогательному классу принимать экземпляр IAccount в качестве параметра (позволяющий передавать какой-либо конкретный тип учетной записи.) Этот интерфейс содержал все общие свойства по 3-4 конкретным классам. Важно отметить, что для создания общих методов, которые я мог бы назвать всеми классами, я не смог использовать какие-либо другие свойства, специфичные для этого класса.

В рамках вспомогательных методов мне нужно было переключить конкретный экземпляр XYZEntities на более общий объект ObjectContext и затем использовать явно такие методы, как AddObject, а не AddBankAccountForm, AddCreditCardForm и т.д. Это включало крошечный бит GetType() для обеспечения того, чтобы объект был передан правильному объекту ObjectSet, но, похоже, работает по своему желанию.

Ответ 2

Для этого есть 3 шаблона:

  • Таблица для иерархии классов. Все конкретные типы в наследственной иерархии хранятся в одной таблице.
  • Таблица для каждого типа. Каждый тип в наследовании хранится в собственной таблице.
  • Таблица для конкретного класса. Таблица для каждого конкретного класса, но нет таблицы для абстрактного класса.

В вашем случае с существующими таблицами класс Table per Concrete выглядит наилучшим образом.

В этой книге есть хорошее описание этих вариантов