流畅的NHibernate三级子类映射

时间:2017-03-24 18:07:13

标签: inheritance fluent-nhibernate fluent-nhibernate-mapping

我有一个复杂的NHibernate结构来存储我们的3级产品层次结构。当我尝试保存在级别3(ProductDetail2)时,我收到以下错误:

  

行被另一个事务更新或删除(或未保存的值映射不正确):[Domain.Models.ProductDetail2#193150]

如果我跳过3级保存逻辑,那一切都很顺利。

我们的类继承如下所示。 ProductDetail1和ProductDetail2是相同的,除了具有不同的ProductType(由于历史原因)

public abstract class Product {
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual int ProductTypeId { get; set; } 
    ...(other core product data)...
}
public class ProductDetail1 : Product {
    public string ShortDescription { get; set; }
    public override int ProductTypeId {
        get { return (int)ProductTypeEnum.ProductOne; }
    }
}
public class ProductDetail2 : ProductDetail1 {
    public override int ProductTypeId {
        get { return (int)ProductTypeEnum.ProductTwo; }
    }
}

根据Fluent Mapping

中的定义,我们必须使用两种不同类型的子类映射
  • Product and ProductDetail1保存到不同的表 - 每子类表映射
  • ProductDetail1和ProductDetail2保存到同一个表 - 每层次表映射(这是因为区分它们的唯一因素是ProductTypeId)

我们的Fluent映射如下

public class ProductMap : ClassMap<Product> {   
  public ProductMap() {   
    Table("Product");
    Id(x => x.Id).GeneratedBy.Identity();
    Map(x => x.Name);
    DiscriminateSubClassesOnColumn("ProductTypeId", 0); 
  }
}

public class ProductDetail1Map : SubclassMap<ProductDetail1> {
    public ProductDetail1Map() {
        Table("ProductDetail"); 
        DiscriminatorValue((int)ProductTypeEnum.ProductOne);
        Join(
            "ProductOne", 
            y => {
                y.KeyColumn("Id");
                y.Map(x => x.ShortDescription);
            });
    }
}

public class ProductDetail2Map : SubclassMap<ProductDetail2> {
    public ProductDetail2Map() {
        DiscriminatorValue((int)ProductTypeEnum.ProductTwo);
    }
}

这可能吗?如果是这样,我做错了什么?

P.S。我也发现了这个类似的post,但它与我们的情况不同,它在1级定义(并保存)Discriminator列,而我们在0级定义它。

1 个答案:

答案 0 :(得分:0)

谢天谢地进行回归测试!!!

上述问题是由失败的测试遇到的。在调查失败后,我们能够识别出不一致的数据,这是(正确地)导致NHibernate错误。

上面概述的Fluent映射确实可以正常运行NHibernate spec - Para 8.1.4