2010-08-03 4 views
8

Sto provando a caricare tutte le raccolte con impazienza, usando NHibernate 3 alpha 1. Mi chiedo se questo è il modo giusto di usare ThenFetch()?È questo il modo giusto di utilizzare ThenFetch() per caricare più raccolte?

Le proprietà con nomi plurali sono raccolte. Gli altri sono solo un singolo oggetto.

  IQueryable<T> milestoneInstances = Db.Find<T, IQueryable<T>>(db => 
      from mi in db 
      where mi.RunDate == runDate 
      select mi).Fetch(mi => mi.Milestone) 
       .ThenFetch(m => m.PrimaryOwners) 
       .Fetch(mi => mi.Milestone) 
       .ThenFetch(m => m.SecondaryOwners) 
       .Fetch(mi => mi.Milestone) 
       .ThenFetch(m => m.Predecessors) 
       .Fetch(mi => mi.Milestone) 
       .ThenFetch(m => m.Function) 
       .Fetch(mi => mi.Milestone) 
       .ThenFetchMany(m => m.Jobs) 
       .ThenFetch(j => j.Source) 
       ; 

ho pensato di chiedere questo nel NHibernate forums ma purtroppo l'accesso a gruppi di Google è proibito da dove mi trovo. So che lo Fabio è qui, quindi forse i ragazzi del team di NHibernate possono far luce su questo? Grazie

risposta

3

L'unica cosa che ti manca è che dovresti usare FetchMany() e ThenFetchMany() è la proprietà figlio è una raccolta.

7

Apparentemente, non esiste un modo "giusto" per utilizzare ThenFetch in questo caso. Il tuo esempio funziona bene ma SQL prodotto contiene molti join a Milestone, che non è quello giusto.

Utilizzando IQueryOver invece di IQueryable consente di utilizzare complex syntax in Fetch:

Fetch(p => p.B) 
Fetch(p => p.B.C) // if B is not a collection ... or 
Fetch(p => p.B[0].C) // if B is a collection ... or 
Fetch(p => p.B.First().C) // if B is an IEnumerable (using .First() extension method) 

Quindi nel tuo caso sarebbe:

query // = session.QueryOver<X>() 
    .Fetch(mi => mi.Milestone).Eager 
    .Fetch(mi => mi.Milestone.PrimaryOwners).Eager 
    .Fetch(mi => mi.Milestone.SecondaryOwners).Eager 
    .Fetch(mi => mi.Milestone.Predecessors).Eager 
    .Fetch(mi => mi.Milestone.Function).Eager 
    .Fetch(mi => mi.Milestone.Jobs).Eager 
    .Fetch(mi => mi.Milestone.Jobs.First().Source).Eager 
+0

+1, non posso credere che funzioni effettivamente. Grazie. –

0

Come ha detto Leora, assicurarsi che quando va a prendere le collezioni per bambini che usi

FetchMany() 

ThenFetchMany() 

Un nuovo recupero, dovrebbe prelevare dalla radice, ma questo non sempre accade. A volte è necessario crearli come query separate o utilizzare Criteria Futures per raggruppare una raccolta multipla.

0
 IQueryable<T> milestoneInstances = Db.Find<T, IQueryable<T>>(db => 
     from mi in db 
     where mi.RunDate == runDate 
     select mi); 

var fetch = milestoneInstances.Fetch(f => f.Milestone); 
fetch.ThenFetch(f => f.PrimaryOwners); 
fetch.ThenFetch(f => f.SecondaryOwners); 
//...