2010-09-07 23 views
5

Questa non è una domanda in quanto tale, ho svolto ricerche su questo argomento negli ultimi giorni e ho pensato che avrei voluto contribuire con qualcosa che tirasse fuori le idee disparate che ho Ho letto e proposto la mia soluzione al problema ...Eager caricamento di albero/gerarchie utilizzando Nhibernate

Il problema è il carico impaziente di oggetti figlio di livello n all'interno di Nibernato e che ibernato non conoscerà la profondità dell'albero. Ho visto questo risolto usando straight sql e Union All, ma sfortunatamente non sono riuscito a farlo funzionare, di solito perché nhibernate non sa che hai caricato gli oggetti. Così ho guardato il seguente codice per eager loading un oggetto utilizzando il criterio

 var children = Session.CreateCriteria<MenuNode>() 
      .SetFetchMode("Children", FetchMode.Eager) 
      .Add(Expression.Eq("Id", 1)) 
      .List<MenuNode>(); 

Questo caricherà ansiosi il bambino per Id 1, da qui è possibile utilizzare l'istruzione per caricare desiderosi più entità in una sola volta. Quindi ho solo bisogno di elaborare tutti gli id ​​dei nodi che appartengono a questa gerarchia e caricarli con impazienza usando l'istruzione In.

Quindi, se ho creare una tabella padre alla gerarchia e ogni nodo ha un ID gerarchia allora posso ottenere una lista di tutti i nodi id per questa gerarchia di utilizzare questo HQL

var sql = "select Distinct id from Nodes where (HierarchyId = :id) "; 
var ids = Session.CreateSQLQuery(sql) 
      .SetInt32("id", id) 
      .List(); 

e da qui carico desiderosi tutti i bambini di questo albero da solo utilizzando

var children = Session.CreateCriteria<MenuNode>() 
      .SetFetchMode("Children", FetchMode.Eager) 
      .Add(Expression.In("Id", ids)) 
      .List<MenuNode>(); 

l'unico problema di questo è che non avete voglia caricato i primi livelli livello di nodi dalla tabella padre della gerarchia, che può essere fatto normalmente ..

01.235.

In questo modo, in tre istruzioni SQL hai caricato un oggetto figlio su n livelli. Per ottimizzare ulteriormente ho utilizzato una query multipla per collegare le due query principali insieme e inviare entrambe le istruzioni contemporaneamente. La dichiarazione per ritirare la necessità dell'ID di eseguire indipendentemente per ritirare l'id.

Ulteriori dettagli dell'utilizzo di multicriteriale a carico ansiosi possono essere trovati qui ..

http://nhforge.org/blogs/nhibernate/archive/2008/09/06/eager-loading-aggregate-with-many-child-collections.aspx

Spero che questo di qualche aiuto a qualcuno

risposta

2

mi rendo conto che non stai chiedendo una domanda, ma Ho pensato di condividere il modo in cui preferisco farlo. Vedo http://ayende.com/Blog/archive/2009/08/28/nhibernate-tips-amp-tricks-efficiently-selecting-a-tree.aspx

return session.CreateCriteria<MenuNode>() 
    .SetFetchMode("Children", FetchMode.Join) 
    .SetResultTransformer(new DistinctRootEntityResultTransformer()) 
    .List<MenuNode>(); 

Non so se questo compie tutto ciò che si intende realizzare con il vostro approccio, ma ho trovato ad essere uno strumento molto utile quando si tratta di dati gerarchici.

Problemi correlati