我有一個3級的實體層次結構:Customer-Order-Line,我想使用ISession.Get(id)爲給定的客戶完整檢索。我有以下XML片段:NHibernate渴望獲取多個級別
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:
<bag name="Lines" cascade="all-delete-orphan" inverse="false" fetch="join">
<key column="OrderID" />
<one-to-many class="Line" />
</bag>
我已經使用了取= 「加入」 屬性,並指示我想爲每個父代獲取子實體,並且這構建了正確的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)的正確數目,我得到錯誤的結果
我應該(從我的測試數據),1xOrder和4xLine,但是,我得到4xOrder和4xLine。看起來NH並不認可結果集中「重複」的訂單信息組,也沒有正確地「重複使用」訂單實體。
我正在使用所有的整數ID(PK),並且我嘗試過使用這個ID實現T和T的IEquatable的IComparable,希望NH能看到這些實體的相等性。我也試過重寫Equals和GetHashCode來使用ID。這些「嘗試」都沒有成功。
NH是否支持「多級提取」操作,如果有,是否需要XML設置(或其他某種機制)來支持它?
注:我用熱風的解決方案與我自己的代碼進行一些修改,終於解決了這一個。 xml需要從bag更改爲set,對於所有集合,並且實體本身已更改爲實現IComparable <>,這是要建立唯一性集合的要求。
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(我的模型在保存時會提供它們)。
[這個答案](http://stackoverflow.com/questions/5266180/fighting-cartesian-product-x-join-when-using-nhibernate-3-0-0/5285739#5285739)幫助我看看如何使用QueryOver和Future查詢來熱切地獲取子孫,而不會返回重複項。該技術涉及將任務分解成單獨的SQL查詢,這些SQL查詢在數據庫的一個往返中執行。 – 2011-10-20 20:29:56