2009-09-01 3 views
7

У меня есть иерархия наследования с базовым объектом Employee и некоторыми дочерними объектами для определенных типов сотрудников. Мне нужно преобразовать базовый объект Employee в более конкретный объект (например, TemporaryEmployee) и от более конкретного типа обратно к базовому типу (например, если сотрудник перестает быть «временным», то я хочу, чтобы этот экземпляр просто был сохраняется в качестве Employee. В DB это просто вопрос добавления или удаления строки из таблицы для конкретного подкласса. (Я использую таблицу для каждого класса.) Я не вижу, как это сделать, используя EF-вызовы, хотя .Изменение типа объекта (Entity Framework), являющегося частью иерархии наследования

ответ

4

Технически вы можете достичь этого, используя хранимую процедуру. TPT не поддерживает его.

Однако я полностью согласен с Крейгом. В классических шаблонах Design Book Design (Addison-Wesley Professional) авторы обсуждают наследование и композицию и заключают, что нужно «одобрять композицию над наследованием».

+0

Да, сейчас я реализовал это с помощью хранимых процедур. Это также была рекомендация от MSFT: «Вы не можете сделать это непосредственно в Entity Framework. Лучше всего будет писать хранимые процедуры для этих преобразований» http://social.msdn.microsoft.com/Forums/ EN-US/adodotnetentityframework/резьба/860d7913-7baa-43e9-a2a7-83b25ad9c558 / –

7

Один из принципов ООП заключается в том, что экземпляры не могут изменить свой тип. Подумайте: можете ли вы сделать это с помощью обычных объектов .NET? Конечно, нет. Вы не можете выполнить конец этого жесткого и быстрого правила сохраняя их с помощью EF.

Добавление строки в БД не изменяет тип экземпляра e, либо; это просто ложь EF о том, что вы сохранили. В реляционном домене вы добавляете отношение, а не изменяете класс объекта, потому что реляционный домен не знает об объектах.

Таким образом, длинный и короткий из этого заключается в том, что использование EF не изменяет правило .NET, которое экземпляры не могут изменить свой тип.

Что делать, если вам нужно это сделать? Ну, подумайте, как это работает в вашей проблемной области. Сотрудник - это человек. Их статус занятости связан с человеком, но их статус на самом деле не является лицом.

Используйте композицию вместо наследования. Я бы, вероятно, смоделировал это как Личность с коллекцией экземпляров занятости. По мере изменения ситуации занятости человека вы можете назначить даты остановки/завершения для старых записей и добавить новые записи для новых заданий.

Сегодня утром я узнал this blog post, что может быть дополнительным пищей для размышлений.

Отредактировано для добавления Если вы работаете с этим путем реализации хранимой процедуры БД, убедитесь, что никто не использует систему в момент ее выполнения. Поскольку это полностью незаконно в пространстве объектов .NET, Entity Framework предполагает, что этого не может быть. Если вы обойдете платформу Entity Framework и сделаете это, и у пользователя в то время есть живой объект ObjectContext, тогда этот объект ObjectContext будет не синхронизирован с базой данных таким образом, чтобы нормальная оптимистическая защита параллелизма в Entity Framework не обнаруживала , Вы не будете повреждать данные, но пользователь с активным объектом ObjectContext может видеть некоторые невероятно странные ошибки.

+1

Хорошие комментарии. Наследование здесь кажется более естественным, поскольку оно позволяет мне определять отношения между более конкретными типами. Да, интересное сообщение блога, на которое вы ссылаетесь, также - изменение сущности на базовый тип - это форма удаления - возможно, я не должен этого делать ... –

+0

О вашем добавленном редактировании: EF не может и не может предположить что это единственный процесс обновления базы данных. Фактически, в большинстве случаев это не так: вы, по крайней мере, должны иметь по меньшей мере несколько экземпляров объекта ObjectContext, работающих против одного и того же БД (например, один на пользователя в случае веб-приложения). –

+0

Я не сказал, что EF предполагает, что это единственный процесс обновления БД, потому что это было бы неправильно.Я сказал, что он возвращает странные сообщения об ошибках, когда какой-то внешний процесс «развращает» базу данных. И EF рассматривает изменение типа экземпляра коррупции по очень веским причинам. Это только проблема, если (1) есть активный контекст объекта с объектом в памяти, тогда (2) какой-то другой пользователь «меняет тип», тогда (3) исходный контекст что-то делает с объектом. EF обнаружит проблему и вернет очень техническую ошибку. Как я уже сказал, это не многопользовательская безопасность. –

Смежные вопросы