在建模领域类时,我发现Entity Framework可以建模继承关系,但不支持将基类型实例提升为派生类型,即无法更改数据库中现有Person行的类型为它的派生类型Employee。
显然,我并不是第一个对此感到困惑的人,因为这个问题已经在Stack Overflow上被问过和回答过多次(例如,见这里和这里)。
正如这些答案所指出的那样,Entity Framework不支持这个功能,因为面向对象编程也不允许这样做:一旦创建了一个实例,就不能更改它的运行时类型。
从技术角度来看,我可以理解这一点。一旦为对象分配了一块内存,后来再添加一些额外的字节来保存派生类型的字段可能需要整个内存块重新分配,这将导致对象的指针发生变化,进而引入更多问题。因此,我明白这很难实现,因此在C#中不支持。
然而,除了技术组件之外,答案(以及这里,在第1页的最后一段)似乎也意味着当你想要更改对象的运行时类型时,这被认为是不良设计,并说你不应该需要这种类型的更改,而应该使用组合来代替。
老实说,我不明白为什么——我认为希望像处理Person实例一样处理Employee实例(即通过从Person继承Employee)是完全有效的,即使在某个时间点上,Person将被聘用为Employee,或者Employee辞职并重新成为Person。
从概念上讲,我认为这没有任何问题?
有人能解释一下吗?
显然,我并不是第一个对此感到困惑的人,因为这个问题已经在Stack Overflow上被问过和回答过多次(例如,见这里和这里)。
正如这些答案所指出的那样,Entity Framework不支持这个功能,因为面向对象编程也不允许这样做:一旦创建了一个实例,就不能更改它的运行时类型。
从技术角度来看,我可以理解这一点。一旦为对象分配了一块内存,后来再添加一些额外的字节来保存派生类型的字段可能需要整个内存块重新分配,这将导致对象的指针发生变化,进而引入更多问题。因此,我明白这很难实现,因此在C#中不支持。
然而,除了技术组件之外,答案(以及这里,在第1页的最后一段)似乎也意味着当你想要更改对象的运行时类型时,这被认为是不良设计,并说你不应该需要这种类型的更改,而应该使用组合来代替。
老实说,我不明白为什么——我认为希望像处理Person实例一样处理Employee实例(即通过从Person继承Employee)是完全有效的,即使在某个时间点上,Person将被聘用为Employee,或者Employee辞职并重新成为Person。
从概念上讲,我认为这没有任何问题?
有人能解释一下吗?
public class Person
{
public string Name { get; set; }
}
public class Employee: Person
{
public int EmployeeNr { get; set; }
public decimal Salary { get; set; }
}
......但这不是吗?
public class Person
{
public string Name { get; set; }
public EmployeeInfo EmployeeInfo { get; set; }
}
public class EmployeeInfo
{
public int EmployeeNr { get; set; }
public decimal Salary { get; set; }
}
Employee
可能有的额外属性?例如,如果每个Employee
都有一个Salary
属性,如果你不知道其薪水,你该如何将任意一个Person
晋升为有效的Employee
?更一般地说:在按合同设计时,如何满足对Employee
实例施加的附加规则(例如,具有有效的薪水)? - Mattias Buelenspublic decimal Salary { get; set; }
}`)是糟糕的设计?在我看来,它看起来毫无争议。问题出在哪里? - Jeppe Stig NielsenEmployee employee = (Employee)new Person();
。 - CodeCaster