使用NHibernate从join-subclass加载基类集合

时间:2011-09-14 13:18:40

标签: nhibernate collections primary-key base-class joined-subclass

我有一个包含一些属性的类和一组名称如下:

public class A : BaseObject
{
    private Int32 zindex;
    private Int32 atNmNr;
    private IList<G020_Namen> names = new List<G020_Namen>();
}

然后我有一个类B,它扩展了A类:

public class B : A
{
    private Int32 zindex;
    private String etiketnaam;

    public B() { }

    public virtual Int32 Zindex
    {
        get { return zindex; }
        set { zindex = value; }
    }
}

A和B链接在主键上。类B作为连接子类映射到类A的映射文件中,如下所示:

    <class name="A" table="A" lazy="true" >
<cache usage="read-write"/>
<id name="Zindex" type="Int32" >
  <column name="Zindex" />
  <generator class="assigned" />
</id>
<property name="AtNmNr" type="Int32">
  <column name="ATNMNR"/>
</property>
<bag name="Namen" table="G020_Namen" inverse="true" cascade="all-delete-orphan" fetch="select" lazy="false" >
  <cache usage="read-write"/>
  <key>
    <column name="NMNR" />
  </key>
  <one-to-many class="G020_Namen" />
</bag>
<joined-subclass name="B" table="B" >
  <key column="Zindex" />
  <property name="Zindex" type="Int32">
    <column name="Zindex"/>
  </property>
  <property name="Etiketnaam" type="String">
    <column name="Etiketnaam"/>
  </property>
</joined-subclass>

现在,如果我想使用Criteria检索A的记录,它可以正常工作并加载名称集合。但是,如果我想检索子类B的记录,则不会加载名称集合(在基类A上)。

然后我尝试添加CreateCriteria来映射集合:

        ICriteria crit = session.CreateCriteria(typeof(B))
            .CreateCriteria("Names", NHibernate.SqlCommand.JoinType.InnerJoin);

它产生以下SQL:

SELECT B.Zindex, B.Etiketnaam, G020_Namen.NMNAAM FROM B
INNER JOIN A ON B.Zindex = A.Zindex 
INNER JOIN G020_Namen ON B.Zindex = G020_Namen.NMNR

所以它试图将表与名称链接到子类表B的主键而不是基表A的外键。它应该是:

SELECT B.Zindex, B.Etiketnaam, G020_Namen.NMNAAM FROM B
INNER JOIN A ON B.Zindex = A.Zindex 
INNER JOIN G020_Namen ON A.AtNnNr = G020_Namen.NMNR

问题是:是否可以使NHibernate从具有ICriteria语句的子类加载基类的集合?

谢谢,

Martin van der Linden。

1 个答案:

答案 0 :(得分:0)

您的期望不正确:

  

INNER JOIN G020_Namen ON A.AtNnNr = G020_Namen.NMNR

AtNnNr甚至没有映射。如果你的意思是ATNMNR,它不应该用于连接,因为它是一个没有FK的简单列。请在original problem上添加更多信息:

  

但是如果我想检索子类B的集合的记录   未加载名称(在基类A上)。

什么没装?姓名还是B?没装怎么样?例外或空集合?

作为旁注,您的映射不是最佳的。

  • 看起来您希望急切地加载您的收藏集(lazy="false")。在这种情况下,请使用fetch="join"代替fetch="select"以避免其他SELECT。

  • 您在B类上不需要<property name="Zindex" type="Int32">。如果您使zindex受到保护,您可以从基类中获取此信息。