我有一个继承层次结构,其中包含一个基本的Employee实体和一些用于特定员工类型的后代实体。我需要能够将基础Employee实体转换为更具体的实体(例如TemporaryEmployee),并从更具体的类型转换回基本类型(例如,如果员工不再是“临时”的话,那么我希望该实例只是坚持为员工。 在DB中,这只是在表中为特定子类添加或删除行的问题。 (我每个班级都在使用表格。)虽然我没有看到如何使用EF调用。
答案 0 :(得分:7)
OOP的一个原则是实例无法更改其类型。想一想:你能用普通的.NET对象做到这一点吗?当然不是。你不能通过坚持使用EF来彻底解决这个严格的规则。
向DB添加行也不会更改实例的类型;关于你所拯救的东西只是骗取EF。在关系域中,您正在添加关系,而不是更改对象的类,因为关系域不了解对象。
因此,长期和短期是使用EF不会更改实例无法更改其类型的.NET规则。
当你需要这样做时,你应该怎么做呢?好吧,想想你的问题域如何运作。员工是一个人。他们的就业状况与此人有关,但他们的身份实际上并不是这个人。
使用合成而不是继承。我可能会将其建模为Person,其中包含一组Employment实例。当一个人的就业情况发生变化时,您可以为旧记录分配停止/终止日期,并为新作业添加新记录。
今天早上我正好读了this blog post,这可能是值得深思的。
编辑添加如果通过实施数据库存储过程解决此问题,请确保在执行时没有人实际使用系统。因为这在.NET对象空间中是完全非法的,所以实体框架假定它不会发生。如果绕过Entity Framework并执行它,并且用户当时碰巧有一个实时ObjectContext,那么此ObjectContext将与数据库不同步,其方式是实体框架中的常规乐观并发保护未检测到。您不会损坏数据,但具有活动ObjectContext的用户可能会看到一些非常奇怪的错误。
答案 1 :(得分:4)
从技术上讲,您可以使用存储过程来实现它。 TPT不支持它。
但是,我完全赞同克雷格。在经典编程书籍“设计模式”(Addison-Wesley Professional)中,作者讨论了继承与构成,并得出结论:人们应该“赞成合成而不是继承”。