2010-08-06 6 views
0

J'ai une structure arborescente de base qui est stockée dans une seule table. Disons que c'est mon modèle:NHibernate: requêtes récursives

public class TreeNode { 
    public virtual Guid Id { get; private set; } 
    public virtual string Name { get; private set; } 
    public virtual IEnumerable<TreeNode> Contents { get; private set; } 
} 

et la table:

TREE_NODES 
    PK_NODE Guid 
    FK_NODE_PARENT Guid 

NODE_NAME Varchar

Je veux la mise en œuvre suivante où la valeur de retour est un TreeNode avec le plein arbre avec impatience chargé de ses enfants et leurs enfants, etc.

public class Tree { 
    ISessionFactory _sessions; 
    public TreeNode GetBy(Guid id) { 
    using(var s = _sessions.OpenSession()) 
     return s.Linq<TreeNode>().Single(n => n.Id == id); 
    } 
} 

Comment le ferais-je? Apping?

Répondre

1

Je doute que vous puissiez l'optimiser - il n'y a pas de recurition dans le SQL de base. Vous pouvez l'optimiser en utilisant des procédures côté serveur (spécifiques au serveur - certains serveurs, comme MySQL ne les supporte pas) mais cela reste douteux car vous obtenez des composants non récursifs.

Probablement le meilleur moyen est de descendre l'arbre dans la fonction de chargement et de forcer l'évaluation. Quelque chose comme:

public class TreeNode { 
    public virtual Guid Id { get; private set; } 
    public virtual string Name { get; private set; } 
    public virtual IEnumerable<TreeNode> Contents { get; private set; } 
} 

public class Tree { 
    ISessionFactory _sessions; 
    public TreeNode GetBy(Guid id) { 
    using(var s = _sessions.OpenSession()) { 
     return LoadSubTree(s.Linq<TreeNode>().Single(n => n.Id == id)); 
    } 
    } 
    private LoadSubTree(TreeNode node) { 
    foreach(var n in node.Contents) 
     LoadSubTree(n); 
    } 
} 

PS. Tree n'est probablement pas le meilleur endroit pour ISessionFactory.

+0

Pouvez-vous élaborer sur «descendre l'arbre dans la fonction de chargement et de forcer l'évaluation»? Je ne sais pas ce que ça veut dire. Qu'est-ce qu'une fonction de chargement par rapport à nhibernate? –

+0

Oui, c'est juste un exemple de code. Tree est plus un référentiel sans état qu'une entité. J'ai trouvé cet article sur les hiérarchies dans NH: http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/05/14/how-to-map-a-tree-in-nhibernate.aspx –

+0

Voici un autre exemple pour référence : http://refactoringaspnet.blogspot.com/2011/04/using-common-table-expressions-to.html –