Fluent NHibernate与同一超类的不同子类型有许多关系

Fluent NHibernate与同一超类的不同子类型有许多关系,nhibernate,fluent,table-per-type,Nhibernate,Fluent,Table Per Type,我正在使用Fluent Nhibernate进行自动映射,由于我当前的继承关系,在设置双向HasMany关系时遇到问题 我的代码的简化版本如下所示 public abstract class BaseClass { public BaseClass Parent { get; set; } } public class ClassA : BaseClass { public IList<ClassB> BChilds { get; protected set; }

我正在使用Fluent Nhibernate进行自动映射,由于我当前的继承关系,在设置双向HasMany关系时遇到问题

我的代码的简化版本如下所示

public abstract class BaseClass
{
    public BaseClass Parent { get; set; }
}

public class ClassA : BaseClass
{
    public IList<ClassB> BChilds { get; protected set; }
    public IList<ClassC> CChilds { get; protected set; }
}

public class ClassB : BaseClass
{
    public IList<ClassD> DChilds { get; protected set; }
}

public class ClassC : BaseClass
{
}

public class ClassD : BaseClass
{
}
公共抽象类基类
{
公共基类父{get;set;}
}
公共类ClassA:基类
{
公共IList BChilds{get;protected set;}
公共IList CChilds{get;protected set;}
}
公共类ClassB:基类
{
公共IList DChilds{get;protected set;}
}
公共类ClassC:基类
{
}
公共类ClassD:基类
{
}
每个类可以有一个父类,有些父类可以有两种类型的子类。我使用每种类型的表继承来生成表

  • “基类”
  • “A类”
  • “B类”
  • “C类”
  • “D类”
为了获得有效的双向映射,我做了以下覆盖 (来自ClassA的一个示例)

mapping.HasMany(x=>x.BChilds).KeyColumn(“Parent_Id”);
mapping.HasMany(x=>x.CChilds).KeyColumn(“Parent_Id”);
这在只有一种子类型的类上可以很好地工作,但有两种子类型的ClassA将在每个列表中获得BaseType的所有子类型,这当然会导致异常。我已经研究了两种不同的解决方法,但没有一种感觉真的足够了,我真的相信有更好的方法来解决它

解决方案1:指向HasMany映射中的具体子类型。(更新了更多信息)

mapping.HasMany(x=>x.BChilds).KeyColumns(“Parent_Id”);
(BaseType替换为ClassB)

使用此映射,NHibernate在某些情况下会在ClassB表中查找名为Parent_Id的列,显然不存在这样的列,因为它属于基类表。只有在ClassA select过程中添加基于BCHILD的语句时,才会出现此问题。e、 g加载ClassA的实体,然后调用ClassA.BChilds似乎可行,但执行查询(使用NHibernateLQ)类似

Query<ClassA>().Where(c => c.BChilds.Count == 0) 
Query()。其中(c=>c.BChilds.Count==0)
将使用错误的表格。因此,我必须手动在此表中创建一个同名的新列,并复制所有值。这是可行的,但风险很大,根本不灵活

解决方法2:在基类中添加一列,告诉具体类型,并在HasMany映射中添加where语句

(更新工作区1后,我不再确定这是否是可行的解决方案)


通过添加一个列,它们的方式与使用带有鉴别器值的每个层次结构表继承时的方式相同。i、 e BaseType表将获得一个值为ClassA、ClassB。。。考虑到NHibernate整体上处理继承的能力,通过阅读NHibernate手册,我相信在每种类型的表中不应该需要鉴别器,似乎NHibernate已经在做硬部分了,并且应该能够以干净的方式处理这一点,而无需添加新列,只是不知道怎么做

基类映射是什么,子类映射是什么样子的? 你应该能做到

mapping.HasMany(x => x.BChilds);
有了正确的映射,就不会有问题了。 如果是流利的nhibernate,请查看

UseUnionSubclassForInheritanceMapping();

我正在使用自动映射,因此除了上述覆盖之外,我没有任何真正的类映射<代码>mapping.HasMany(x=>x.BChilds);应该与mapping.HasMany(x=>x.BChilds)相同即与我的解决方案1相同(使用了错误的表),我将查看UseUnionSubclass ForInheritanceMapping();查看UseUnionSubclassForInheritanceMapping,我的第一个理解是您将使用该方法或鉴别器技术。通过将其添加到映射中,我没有注意到任何不同,因此我怀疑这是已经在使用的策略。我将详细阐述一下我的问题,关于错误表的问题何时出现,在反复测试之后,我忘记了一些问题。基本上,如果按照上面的映射加载ClassA对象,那么调用ClassA.BChilds将给出正确的结果,但是NHibernateLQ查询将使用错误的表。
mapping.HasMany(x => x.BChilds);
UseUnionSubclassForInheritanceMapping();