Когда я определяю модель в Entity Framework с наследованием таблиц по типам, если у меня есть базовый класс / таблица (не абстрактная) с именем person, и две дочерние сущности и таблицы, взрослый и дочерний, после создания дочернего элемента, как бы я взять тот же объект и преобразовать его во взрослый? После преобразования во взрослую запись дочерняя запись должна быть удалена, хотя данные базового класса в таблице людей должны быть сохранены.
Модель Entity Framework с наследованием таблиц по типам
Ответы (2)
Это невозможно. Это аналогичная проблема, аналогичная здесь. Просто сущность существует и ее тип неизменен. Единственный способ сделать это - удалить дочерний объект (= записи из обеих таблиц) и создать новый взрослый объект (= новые записи для обеих таблиц).
Это вообще не похоже на сценарий наследования.
Редактировать:
Комментарий о наследовании предназначен для сценария, в котором вы упомянули объекты Person
, Adult
и Child
. В любом случае, как только ваш сценарий позволяет изменить тип, вы должны подумать о другом решении, в котором часть, которая может измениться, будет обрабатываться композицией.
Например:
public class DataSource
{
public int Id { get; set; }
public virtual DataSourceFeatures Features { get; set; }
}
public class DataSourceFeatures
{
[Key, ForeignKey("DataSource")]
public int Id { get; set; }
public virtual DataSource DataSource { get; set; }
}
public class XmlDataSourceFeatures : DataSourceFeatures { ... }
public class DelimitedDataSourceFeatures : DataSourceFeatures { ... }
public class ServiceDataSourceFeatures : DataSourceFeatures { ... }
Теперь изменение типа означает удаление зависимого текущего DataSourceFeatures
из базы данных и создание нового, но исходный объект остается прежним - изменяется только отношение.
Я бы не стал этого делать с EF, потому что с наследованием вы создали объектно-ориентированную абстракцию над связями таблиц, которая не позволяет вам конвертировать из разных типов. В OO вы не можете делать что-то подобное:
Child child = new Child();
Adult grownUp = child;
А потом ожидайте, что ребенок станет взрослым. Вы бы сделали это так:
Child child = new Child();
Adult grownUp = child.GrowUp();
Предполагая, что вы используете SQL Server, вы можете сделать это с помощью хранимой процедуры. Что-то вроде GrowUp (child), и пусть он создаст новую запись в таблице Adult, а также удалит запись в таблице Child, но оставьте Person нетронутым. Вы можете вернуть новый взрослый объект из процедуры. Затем это можно использовать следующим образом:
Adult grownUp = context.GrowUp(child);
Однако вам нужно убедиться в своем коде, что после этой строки вы больше не используете дочерний объект и вам, вероятно, потребуется обновить или удалить его из контекста (не совсем уверен в этом).