2010-08-03 14 views
8

Estoy intentando cargar todas las colecciones con entusiasmo, usando NHibernate 3 alpha 1. Me pregunto si esta es la forma correcta de usar ThenFetch()?¿Es esta la forma correcta de usar ThenFetch() para cargar varias colecciones?

Las propiedades con nombres en plural son colecciones. Los otros son solo un solo objeto.

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

pensé en preguntarle esto en el NHibernate forums pero desafortunadamente el acceso a los grupos de Google está prohibido desde donde estoy. Sé que Fabio está aquí, así que tal vez los chicos del equipo de NHibernate puedan arrojar algo de luz sobre esto? Gracias

Respuesta

3

Lo único que falta es que debe usar FetchMany() y ThenFetchMany() es que la propiedad secundaria es una colección.

7

Aparentemente, no existe una forma "correcta" de utilizar ThenFetch en tal caso. Su ejemplo funciona bien, pero el SQL producido contiene muchas combinaciones en Milestone, que no es el correcto.

Usando IQueryOver en lugar de IQueryable le permite utilizar complex syntax en 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) 

Así que en su caso sería:

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, no puedo creer que esto realmente funcione. Gracias. –

0

Como dijo Leora, asegúrese de que al ir a buscar colecciones infantiles que usted usa

FetchMany() 

ThenFetchMany() 

Un nuevo Fetch, debería recoger desde la raíz, pero esto no siempre sucede. En ocasiones, debe crearlos como consultas separadas o usar Criteria Futures para generar una búsqueda múltiple.

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); 
//... 
Cuestiones relacionadas