2010-08-03 4 views
8

Ich versuche, alle Sammlungen eifrig zu laden, mit NHibernate 3 alpha 1. Ich frage mich, ob dies der richtige Weg ist, ThenFetch() zu verwenden?Ist dies der richtige Weg, um mit ThenFetch() mehrere Sammlungen zu laden?

Eigenschaften mit Pluralnamen sind Sammlungen. Die anderen sind nur ein einziges Objekt.

  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) 
       ; 

Ich dachte, dies in dem NHibernate forums aber leider den Zugang zu Google Groups zu fragen aus ist verboten, wo ich bin. Ich weiß, Fabio ist hier, also können die Jungs vom NHibernate-Team vielleicht etwas Licht ins Dunkel bringen? Danke

Antwort

3

Die einzige Sache, die Sie vermissen, ist, dass Sie FetchMany() und ThenFetchMany() verwenden sollten, ist die Kind-Eigenschaft eine Sammlung.

7

Anscheinend gibt es keinen "richtigen" Weg, ThenFetch in solch einem Fall zu verwenden. Ihr Beispiel funktioniert gut, aber SQL produziert enthält viele Verknüpfungen zu Milestone, was nicht richtig ist.

Mit IQueryOver statt IQueryable können Sie complex syntax in Fetch verwenden:

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) 

Also in Ihrem Fall wäre es:

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, kann nicht glauben, dass das tatsächlich funktioniert. Vielen Dank. –

0

Wie leora sagte, sicher, wenn Kinder Sammlungen holen, dass Sie verwenden

FetchMany() 

ThenFetchMany() 

Ein neuer Fetch, sollte von der Wurzel abholen, aber das passiert nicht immer. Manchmal müssen Sie sie als separate Abfragen erstellen oder Criteria Futures verwenden, um einen Mehrfachabruf zu verarbeiten.

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); 
//... 
Verwandte Themen