J'ai une hiérarchie à trois niveaux d'entités: Customer-Order-Line, que je voudrais récupérer en entier pour un client donné, en utilisant ISession.Get (id). Je les fragments XML suivants:NHibernate Eager Récupération sur plusieurs niveaux
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>
Je l'ai utilisé fetch = "join" attribut pour indiquer que Je veux récupérer les entités enfants pour chaque parent, et cela a construit le bon 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
Jusqu'à présent, cela ressemble bon - SQL retourne l'ensemble correct d'enregistrements (avec un seul orderid distinct), mais quand j'exécute un test pour confirmer le bon nombre d'entités (de NH) pour les commandes et les lignes, j'obtiens des résultats erronés
I I devrait obtenir (à partir de mes données de test), 1xOrder et 4xLine, cependant, je reçois 4xOrder et 4xLine. Il semble que NH ne reconnaisse pas le groupe «répétitif» des informations de commande dans le jeu de résultats, ni ne «réutilise» correctement l'entité de commande. J'utilise tous les nombres entiers (PKs), et j'ai essayé d'implémenter IComparable de T et IEquatable de T en utilisant cet ID, dans l'espoir que NH verra l'égalité de ces entités. J'ai également essayé de surenchérir Equals et GetHashCode pour utiliser l'ID. Aucune de ces «tentatives» n'a réussi.
Est-ce que «multiple leveled fetch» est une opération prise en charge pour NH, et si oui, y a-t-il un paramètre XML requis (ou un autre mécanisme) pour le prendre en charge? NB: J'ai utilisé la solution de Sirocco avec quelques modifications à mon propre code pour finalement résoudre celle-ci. le xml doit être changé de bag à set, pour toutes les collections, et les droits eux-mêmes ont été changés pour implémenter IComparable <>, qui est une exigence d'un ensemble pour l'unicité à établir.
Notez l'utilisation d'un champ ID interne. Ceci est requis pour les nouvelles entités (transitoires), sinon ils n'auront pas d'ID initialement (mon modèle les a fournis lors de leur sauvegarde).
[Cette réponse] (http://stackoverflow.com/questions/5266180/fighting-cartesian-product-x-join-when-using-nhibernate-3-0-0/5285739#5285739) m'a aidé à voir comment utiliser les requêtes QueryOver et Future pour récupérer les enfants et les petits-enfants sans retourner les doublons. La technique consiste à décomposer la tâche en différentes requêtes SQL qui sont exécutées dans un seul aller-retour à la base de données. –