您需要实现自己的IUserType。
请参考这篇博客文章了解详情。如果该博客消失,下面也会贴出相关部分。
在NHibernate中,自定义映射类型是从IUserType或ICompositeUserType接口派生的类。这些接口包含必须实现的多个方法,但为了本文的目的,我们将专注于其中的两个方法。请看下面的示例。
public class TypeClassUserType : IUserType
{
object IUserType.NullSafeGet(IDataReader rs,
string[] names,
object owner) {
string name = NHibernateUtil.String.NullSafeGet(rs,
names[0]) as string;
TypeClassFactory factory = new TypeClassFactory();
TypeClass typeobj = factory.GetTypeClass(name);
return typeobj;
}
void IUserType.NullSafeSet(IDbCommand cmd,
object value,
int index) {
string name = ((TypeClass)value).Name;
NHibernateUtil.String.NullSafeSet(cmd, name, index);
}
}
完成了这个类的创建后,现在我可以将ActualClass和TypeClass之间的关联显式地映射为ActualClass映射中的一个简单属性。
<property
name="Type"
column="TypeName"
type="Samples.NHibernate.DataAccess.TypeClassUserType,
Samples.NHibernate.DataAccess" />
当NHibernate正在保存一个ActualType实例时,它将加载并创建一个新的TypeClassUserType实例,并调用NullSafeSet方法。从方法体中可以看到,我只是从映射属性(以value参数传递)中提取名称,并将提取的名称设置为要在数据库中设置的参数的值。最终结果是,虽然实体模型中的ActualClass的Type属性是TypeClass,但只有TypeClass对象的Name属性存储在数据库中。反之亦然。当NHibernate从数据库加载ActualType实例并找到自定义映射类型的属性时,它会加载我的自定义类型并调用NullSafeGet方法。可以看到,我的方法从返回的数据中获取名称,调用我的享元工厂获取正确的TypeClass实例,然后实际返回该实例。类型解析过程对我的数据访问类(甚至对NHibernate本身)来说是透明的。