1

我有一个具有一些属性和一组名称的类,如下所示:

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 语句从子类加载基类上的集合?

谢谢,

马丁范德林登。

4

1 回答 1

0

您的期望不正确:

内部连接 ​​G020_Namen ON A.AtNnNr = G020_Namen.NMNR

AtNnNr 甚至没有被映射。如果您的意思是 ATNMNR,则不应在 join 中使用它,因为它是一个没有 FK 的简单列。请添加有关原始问题的更多信息:

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

什么没有加载?名字还是B?没装怎么办?异常还是空集合?

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

  • 看起来您希望您的收藏被急切地加载(lazy="false")。在这种情况下,使用fetch="join"而不是fetch="select"避免额外的 SELECT。

  • 您不需要<property name="Zindex" type="Int32">B 类。如果您使 zindex 受保护,您可以从基类中获得它。

于 2011-09-14T14:22:17.700 回答