2010-02-07 6 views
3

Je dispose d'un modèle d'objet comme celui-ci:Nhibernate: résultats distincts en deuxième niveau Collection

class EntityA 
    { 
     ... 
     IList<EntityB> BList; 
     ... 
    } 

    class EntityB 
    { 
     ... 
     IList<EntityC> CList; 
    } 

Je dois aller chercher tous les colelctions (Blist dans l'Entité et CList dans l'Entité), parce que si tous seront nécessaires pour faire quelques opérations, si je ne les charge pas avec empressement, j'aurai le problème de sélection n + 1. Ainsi, la requête était la suivante:

select a from EntityA a left join fetch a.BList b left join fetch b.CList c 

Le problème de poing i face à cette requête, a été le retour des doublons de la DB, j'ai eu des doublons entityA, à cause de la gauche join fetch avec BList. Une lecture rapide à travers la documentation d'hibernation et il y avait quelques solutions, d'abord j'ai essayé le mot clé distinct qui ne serait pas répliquer le mot clé SQL distinct sauf dans certains cas, peut-être c'était un de ces cas je ne peux pas sélectionner les colonnes de texte distict (colonne [Observations] dans la table EntityA). Donc, j'ai utilisé l'une des autres solutions:

query.SetResultTransformer(new DistinctRootEntityResultTransformer()); 

Cela a bien fonctionné. Mais le résultat des opérations ne passait toujours pas les tests. J'ai vérifié plus loin et j'ai découvert que maintenant il y avait des doublons d'EntityB, à cause de la recherche de jointure gauche avec CList. La question est, comment puis-je utiliser le distinct dans une collection de second niveau? J'ai cherché et je ne trouve que des solutions pour la collecte des enfants de l'entité racine directe, mais jamais pour la deuxième collections enfants de niveau ...

Merci pour votre temps

+0

Voir ma réponse à cette [question] [1] (qui est presque une copie identique :-)) [1]: http: // stackoverflow.com/questions/7614661/chargement-multi-niveau-collections-sans-doublons-in-nhibernate/7615646 # 7615646 – Goblin

Répondre

0

Vous ne pouvez pas accomplir ce que vous voulez d'une manière simple. Je crois que c'est la gauche rejoindre chercher de C qui provoque les doublons. La requête générée est quelque chose comme ceci:

select a 
left join a.b b 
left join b.c c 

et les lignes renvoyées par la db sera comme ceci:

1: a1 | b1 | c1 
2: a1 | b1 | c2 
3: a1 | b2 | c3 
4: a1 | b2 | c4 
... 

Althouh vous avez déjà filtré les doublons d'entité racine (A de « s), en raison de la jointure externe sur C, la base de données doit renvoyer des entrées répétées pour la table B pour chacune des entrées C. Un moyen simple de résoudre ce problème est de filtrer les éléments via une collection utilitaire. Selon les exigences de votre Entité, vous pouvez également utiliser un HashSet afin qu'il les filtre automatiquement.

0

Utilisez un ISet au lieu d'un IList (et mappez-le en tant que set hors cours, au lieu d'un sac).

Un ensemble n'autorise pas les entités en double.

+0

Cela ne fonctionne que pour la première collection. La deuxième collection contient toujours des entrées en double. J'ai le même problème ici et je n'ai toujours pas trouvé de solution. –

0

J'ai rencontré le même problème et je n'ai pas réussi à résoudre le problème de duplication via hql. Cependant, j'ai créé IEqualityComparer pour toutes les collections et ai fait Disinct() sur chaque collection pour éliminer les doublons au-dessus du résultat hql.

Questions connexes