मेरे पास इकाइयों का 3-स्तर का पदानुक्रम है: ग्राहक-ऑर्डर-लाइन, जिसे मैं किसी दिए गए ग्राहक के लिए ISession.Get (id) का उपयोग करके पूरी तरह से पुनर्प्राप्त करना चाहता हूं। मैं निम्न 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:
<bag name="Lines" cascade="all-delete-orphan" inverse="false" fetch="join">
<key column="OrderID" />
<one-to-many class="Line" />
</bag>
मैं का इस्तेमाल किया है लाने = "में शामिल होने के" है कि इंगित करने के लिए विशेषता मैं प्रत्येक माता-पिता के लिए बच्चे इकाइयों को लाने के लिए चाहता हूं, और इसने सही एसक्यूएल बनाया है:
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
अभी तक, यह दिखता है अच्छा - एसक्यूएल रिकॉर्ड्स का सही सेट देता है (केवल एक अलग ऑर्डरिड के साथ), लेकिन जब मैं ऑर्डर और लाइन्स के लिए सही संख्या में इकाइयों (एनएच से) की पुष्टि करने के लिए एक परीक्षण चलाता हूं, तो मुझे गलत परिणाम मिलते हैं
I होना चाहिए (मेरे टेस्ट डेटा से), 1xOrder और 4xLine, हालांकि, मुझे 4xOrder और 4xLine मिल रहा है। ऐसा प्रतीत होता है कि एनएच परिणाम सेट में ऑर्डर जानकारी के 'दोहराव' समूह को मान्यता नहीं दे रहा है, न ही ऑर्डर इकाई को सही तरीके से 'पुन: उपयोग' कर रहा है।
मैं सभी पूर्णांक आईडी (पीके) का उपयोग कर रहा हूं, और मैंने आशा व्यक्त की है कि एनएच इन इकाइयों की समानता को देखेगा, इस आईडी का उपयोग कर टी के आईसीओपरटेबल को लागू करने की कोशिश की है। मैंने आईडी का उपयोग करने के लिए बराबर और GetHashCode ओवरराइड करने का भी प्रयास किया है। इन 'प्रयासों' में से कोई भी सफल नहीं हुआ है।
क्या एनएच के लिए एक समर्थित ऑपरेशन "एकाधिक स्तरित fetch" है, और यदि हां, तो क्या इसका समर्थन करने के लिए कोई XML सेटिंग आवश्यक है (या कुछ अन्य तंत्र)?
एनबी: मैंने अंततः इस कोड को हल करने के लिए अपने कोड में कुछ बदलावों के साथ सिरोको का समाधान किया। एक्सएमएल को बैग से सेट में बदलना होगा, सभी संग्रहों के लिए, और अधिकारों को स्वयं आईसीओपरपेबल <> को लागू करने के लिए बदल दिया गया था, जो कि विशिष्टता स्थापित करने के लिए एक सेट की आवश्यकता है।
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
...
}
एक आंतरिक आईडी फ़ील्ड के उपयोग पर ध्यान दें। यह नई (क्षणिक) इकाइयों के लिए आवश्यक है, अन्यथा उनके पास शुरुआत में एक आईडी नहीं होगी (मेरे मॉडल ने उन्हें सहेजे जाने पर आपूर्ति की है)।
[यह उत्तर] (http://stackoverflow.com/questions/5266180/fighting-cartesian-product-x-join-when-using-nhibernate-3-0-0/5285739#5285739) मुझे यह देखने में मदद मिली कि कैसे डुप्लिकेट लौटाए बिना बच्चों और पोते-बच्चों को उत्सुकता से लाने के लिए क्वेरीओवर और भविष्य के प्रश्नों का उपयोग करना। इस तकनीक में कार्य को अलग-अलग SQL क्वेरी में विभाजित करना शामिल है जो डेटाबेस में एक राउंडट्रिप में निष्पादित होते हैं। –