Entity Framework - Абстрактный базовый класс без отображения в таблицу БД - PullRequest
13 голосов
/ 07 ноября 2011

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

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

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

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

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

Есть идеи, как добавить базовый класс таким образом? Или мне просто добавить базовый класс в код и как-то обойти модель?

РЕДАКТИРОВАТЬ: В качестве дополнительной информации, возьмите пример, где есть, скажем, 3 типа, MortageApplicationForm, BankAccountApplicationForm и CreditCardApplication form. В настоящее время они хранятся в 3 разных таблицах с набором различных полей. Я пытаюсь создать базовый класс, скажем, «Форма», в котором будут общие поля.

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

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

Ответы [ 2 ]

4 голосов
/ 24 ноября 2011

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

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

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

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

2 голосов
/ 08 ноября 2011

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

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

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

...