NHibernate将子类转换为父类

时间:2010-08-19 16:59:43

标签: nhibernate

假设以下实体:

public class AppUser
{
    public virtual int Id { get; set; }
    public virtual string Login { get; set; }
}

// Mapped as joined-subclass
public class Person : AppUser 
{
    public virtual int Age { get; set; }
}

如果我创建1个AppUser,并将其保存为

var user = new AppUser() { Login = "test" };
session.Save( user ); // let's say Id = 1

如何将其转换/转换/“推广”给一个人,保持相同的ID?

现在,我在AppUser表中遇到了一行,Id = N.如何使用相同的Id填充Person表?我无法删除AppUser并将其重新创建为Person,因为外键可能会引用AppUser。

我可以发出一个“手动”SQL INSERT,但它有点丑......

这绝对是一个NHibernate的问题。我理解从OOP的角度来看,这没什么意义,因此缺少其他标签而不是nhibernate。

2 个答案:

答案 0 :(得分:1)

这是discussed on SO before,我引用Jon Skeet作为后代:

  

没有。对派生类的引用   实际上必须引用一个实例   派生类(或null)。除此以外   你会怎么期望它表现出来?

     

例如:

object o = new object();
string s = (string) o;
int i = s.Length; // What can this sensibly do?
  

如果你想转换一个   基本类型的实例   派生类型,我建议你写一个   方法来创建一个合适的   派生类型实例。或者看看你的   继承树再次尝试   重新设计,这样你就不需要这样做了   这首先是。

在Skeet的例子中,字符串是对象,对象不是字符串。所以“向上倾斜”是行不通的。

答案 1 :(得分:1)

我不相信nHibernate会为你解决这个问题。 nHibernate正在将您的数据作为对象处理,特别是对于join-subclass,我不相信内置的任何东西允许您动态更改子类类型,或者至少更改类型并保留原始ID。

我认为你最好的办法是编写一个存储过程,给定一个ID和一个NEW类型,从子类表中删除所有条目,并在正确的子类表中添加一个新条目。

一旦proc运行,然后在nHibernate中重新加载对象(并确保你丢弃了与之相关的任何缓存数据),它现在应该是你想要使用的正确类型,设置它的新属性并保存它

这样你就有了一个相对通用的存储过程,它只会改变你的子类类型,但是你不需要添加所有疯狂的逻辑来处理你的子类上的各种属性。