NHibernate渴望获取多个级别 [英] NHibernate Eager Fetching Over Multiple Levels

查看:95
本文介绍了NHibernate渴望获取多个级别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个三级实体层次结构:Customer-Order-Line,我想使用ISession.Get(id)完整地为给定客户检索该实体.我有以下XML片段:

I have a 3-leveled hierarchy of entities: Customer-Order-Line, which I would like to retrieve in entirety for a given customer, using ISession.Get(id). I have the following XML fragments:

customer.hbm.xml:

customer.hbm.xml:

<bag name="Orders" cascade="all-delete-orphan" inverse="false" fetch="join">
  <key column="CustomerID" />
  <one-to-many class="Order" />
</bag>

order.hbm.xml:

order.hbm.xml:

<bag name="Lines" cascade="all-delete-orphan" inverse="false" fetch="join">
  <key column="OrderID" />
  <one-to-many class="Line" />
</bag>

我使用了fetch ="join"属性来表示我想获取每个父级的子级实体,这已经构造了正确的SQL:

I have used the fetch="join" attribute to indicate that I want to fetch the child entities for each parent, and this has constructed the correct SQL:

SELECT 
    customer0_.ID AS ID8_2_, 
    customer0_.Name AS Name8_2_, 
    orders1_.CustomerID AS CustomerID__4_, 
    orders1_.ID AS ID4_, 
    orders1_.ID AS ID9_0_, 
    orders1_.PostalAddress AS PostalAd2_9_0_, 
    orders1_.OrderDate AS OrderDate9_0_, 
    lines2_.OrderID AS OrderID__5_, 
    lines2_.ID AS ID5_, 
    lines2_.ID AS ID10_1_, 
    lines2_.[LineNo] AS column2_10_1_, 
    lines2_.Quantity AS Quantity10_1_, 
    lines2_.ProductID AS ProductID10_1_ 

FROM Customer customer0_ 

LEFT JOIN [Order] orders1_ 
       ON customer0_.ID=orders1_.CustomerID 

LEFT JOIN Line lines2_ 
       ON orders1_.ID=lines2_.OrderID 

WHERE customer0_.ID=1

到目前为止,这看起来不错-SQL返回正确的记录集(只有一个不同的orderid),但是当我运行测试以确认订单和行"的正确实体数(来自NH)时,我得到了错误的结果

So far, this looks good - SQL returns the correct set of records (with only one distinct orderid), but when I run a test to confirm the correct number of entities (from NH) for Orders and Lines, I get the wrong results

应该(从测试数据中)得到1xOrder和4xLine,但是,我得到的是4xOrder和4xLine.看来NH无法识别结果集中的重复"订购信息组,也无法正确地重用"订购实体.

I should be getting (from my test data), 1xOrder and 4xLine, however, I am getting 4xOrder and 4xLine. It appears that NH is not recognising the 'repeating' group of Order information in the result set, nor correctly 'reusing' the Order entity.

我正在使用所有整数ID(PK),并尝试使用此ID实现T的IComparable和T的IEquatable,以希望NH看到这些实体的相等性.我还尝试覆盖Equals和GetHashCode以使用ID.这些尝试"都没有成功.

I am using all integer IDs (PKs), and I've tried implementing IComparable of T and IEquatable of T using this ID, in the hope that NH will see the equality of these entities. I've also tried overridding Equals and GetHashCode to use the ID. Neither of these 'attempts' have succeeded.

NH是否支持多级访存"操作,如果是,是否需要XML设置(或其他某种机制)来支持它?

Is "multiple leveled fetch" a supported operation for NH, and if so, is there an XML setting required (or some other mechanism) to support it?

NB:我使用sirocco的解决方案,并对自己的代码进行了一些更改,最终解决了这一问题.对于所有集合,都需要从包到集更改xml,并且实体本身也要更改为实现IComparable<>,这是建立唯一性的集合的要求.

NB: I used sirocco's solution with a few changes to my own code to finally solve this one. the xml needs to be changed from bag to set, for all collections, and the entitities themselves were changed to implement IComparable<>, which is a requirement of a set for uniqueness to be established.

public class BaseEntity : IComparable<BaseEntity>
{
    ...

    private Guid _internalID { get; set; }
    public virtual Guid ID { get; set; }

    public BaseEntity()
    {
        _internalID = Guid.NewGuid();
    }

    #region IComparable<BaseEntity> Members

    public int CompareTo( BaseEntity other )
    {
        if ( ID == Guid.Empty || other.ID == Guid.Empty )
            return _internalID.CompareTo( other._internalID );

        return ID.CompareTo( other.ID );
    }

    #endregion

    ...

 }

请注意使用InternalID字段.对于新的(临时)实体,这是必需的,否则它们最初将没有ID(我的模型在保存时提供了它们).

Note the use of an InternalID field. This is required for new (transient) entities, other wise they won't have an ID initially (my model has them supplied when saved).

推荐答案

您将获得4XOrder和4XLines,因为与行的连接使结果加倍.您可以在ICriteria上设置一个Transformer,例如:

You're getting 4XOrder and 4XLines because the join with lines doubles the results . You can set a Transformer on the ICriteria like :

.SetResultTransformer(new DistinctRootEntityResultTransformer())

这篇关于NHibernate渴望获取多个级别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆