假设以下实体:
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。
答案 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中重新加载对象(并确保你丢弃了与之相关的任何缓存数据),它现在应该是你想要使用的正确类型,设置它的新属性并保存它
这样你就有了一个相对通用的存储过程,它只会改变你的子类类型,但是你不需要添加所有疯狂的逻辑来处理你的子类上的各种属性。