【问题标题】:Loading collection in base class from joined-subclass with NHibernate使用 NHibernate 从加入子类加载基类中的集合
【发布时间】:2011-09-14 13:18:39
【问题描述】:

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

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

谢谢,

马丁·范德林登。

【问题讨论】:

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


    【解决方案1】:

    你的预期不正确:

    A.AtNnNr 上的内部连接 ​​G020_Namen = G020_Namen.NMNR

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

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

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

    附带说明,您的映射不是最佳的。

    • 您似乎希望快速加载您的收藏集 (lazy="false")。在这种情况下,请使用 fetch="join" 而不是 fetch="select" 以避免额外的 SELECT。

    • B 类不需要&lt;property name="Zindex" type="Int32"&gt;。如果您将 zindex 设为受保护,您可以从基类中获取它。

    【讨论】:

    • 非常感谢您的帮助。您说 AtMnNr 未映射为外键是解决方案。在将 AtMnNr 映射为 后,Nhibernate 能够正确找到具有名称的表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多