当我在Entity Framework中使用Table-per-Type继承定义模型时,如果我有一个名为person的基类/表(不是抽象),以及两个子实体和表(adult和child),在创建子项后,我如何采取相同的对象并将其转换为成人?转换为成人后,应删除子记录,但应保留person表中的基类数据。
答案 0 :(得分:4)
这是不可能的。这与here类似。只是实体存在,其类型是不可变的。唯一的方法是删除子实体(=两个表中的记录)并创建一个新的成人实体(=两个表的新记录)。
这看起来不像继承的场景。
编辑:
有关继承的评论针对您提及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
并创建一个新的但原始对象保持不变 - 只有关系发生变化。
答案 1 :(得分:3)
我不会用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);
但是,您需要在代码中确保在此行之后您不再使用子对象,并且您可能需要刷新或从上下文中删除它(不完全确定这一点)。