这真的很晚了,但可能对下一个想要做类似事情的人有用:
虽然其他答案是正确的,即在大多数情况下您不应该更改鉴别器,但您可以完全在 NH 的范围内(无本机 SQL)进行更改,并巧妙地使用映射属性。这是使用 FluentNH 的要点:
public enum CustomerType //not sure it's needed
{
Customer,
TierOneCustomer
}
public class Customer
{
//You should be able to use the Type name instead,
//but I know this enum-based approach works
public virtual CustomerType Type
{
get {return CustomerType.Customer;}
set {} //small code smell; setter exists, no error, but it doesn't do anything.
}
...
}
public class TierOneCustomer:Customer
{
public override CustomerType Type {get {return CustomerType.TierOneCustomer;} set{}}
...
}
public class CustomerMap:ClassMap<Customer>
{
public CustomerMap()
{
...
DiscriminateSubClassesOnColumn<string>("CustomerType");
DiscriminatorValue(CustomerType.Customer.ToString());
//here's the magic; make the discriminator updatable
//"Not.Insert()" is required to prevent the discriminator column
//showing up twice in an insert statement
Map(x => x.Type).Column("CustomerType").Update().Not.Insert();
}
}
public class TierOneCustomerMap:SubclassMap<TierOneCustomer>
{
public CustomerMap()
{
//same idea, different discriminator value
...
DiscriminatorValue(CustomerType.TierOneCustomer.ToString());
...
}
}
最终结果是为插入指定了鉴别器值,并用于确定检索时的实例化类型,但是如果保存了具有相同 Id 的不同子类型的记录(就好像该记录是从UI 为新类型),则在现有记录上更新鉴别器值,将该 ID 作为对象属性,以便将来对该类型的检索作为新对象。属性需要设置器,因为无法告知 AFAIK NHibernate 属性是只读的(因此对数据库“只写”);在 NHibernate 的世界里,如果你向 DB 写了一些东西,你为什么不想要它回来呢?
我最近使用这种模式来允许用户更改“旅行”的基本类型,这实际上是一组管理实际“旅行”(对客户现场设备的单一数字“访问”)日程安排的规则以确保一切正常)。虽然它们都是“旅游时间表”并且需要在列表/队列等中收集,但不同类型的时间表需要非常不同的数据和非常不同的处理,需要与 OP 类似的数据结构。因此,我完全理解 OP 希望以完全不同的方式对待 TierOneCustomer,同时尽量减少对数据层的影响,所以,来吧。