2011-03-06 11 views
20

que estaba viendo thismúltiples descarge en LINQ a nhibernate

Tenga cuidado de no obtener ansiosamente múltiples propiedades de la colección en el mismo tiempo. Aunque esta afirmación no tendrán ningún problema:

empleados var = session.Query() .Fetch (e => e.Subordinates) .Fetch (e => e.Orders) .ToList();

Necesito buscar 2 referencias, así que tendría que hacer algo así. ¿Hay una mejor manera de hacer esto?

no puedo hacer .ThenFetchMany() ya que va al niño en los objetos, pero los que yo soy después en el mismo nivel.

Respuesta

32

Bueno, la consulta seguirá arrojando los resultados que desee, pero como se indicó, devolverá un producto cartesiano, es decir, la consulta SQL arrojará count(e.Subordinates) * count(e.Orders) resultados, que podrían sumar bastante rápido, especialmente si tiene más que solo dos colecciones.

NHibernate introdujo Futures con el lanzamiento 2.1. Desafortunadamente, parece que no hay forma en la versión actual de NHibernate 3.0 para que funcionen con NHibernate.Linq (session.Query<T>()).

Futuros le permiten realizar varias consultas en una ida y vuelta a la base de datos (siempre y cuando la base de datos lo soporta, pero la mayoría lo hacen). En ese caso, solo tendrá count(e.Subordinates) + count(e.Orders) resultados, que obviamente es el mínimo.

Futuros trabajar con la API de criterios, HQL y se supone que deben trabajar con la nueva API QueryOver (no he probado que, sin embargo).

NHibernate.Linq tiene Query(). ToFuture() y Query(). ToFutureValue(), pero hasta ahora solo recibo Excepciones cuando los uso.

Editar:

acabo de comprobar de nuevo por la API de LINQ y parece como si está funcionando si no utilizar la herramienta Explorar. Lo siguiente dará como resultado tres consultas SQL que se ejecutan en una ida y vuelta. El número total de filas devueltas será 1 + conteo (Subordinados) + conteo (Pedidos).

int id = 1; 

// get the Employee with the id defined above 
var employee = repo.Session.Query<Employee>() 
    .Where(o => o.Id == id) 
    .ToFuture<Employee>(); 

// get the Subordinates (these are other employees?) 
var subordinates = repo.Session.Query<Employee>() 
    .Where(o => o.HeadEmployee.Id == id) 
    .ToFuture<Employee>(); 

// get the Orders for the employee 
var orders = repo.Session.Query<Order>() 
    .Where(o => o.Employee.Id == id) 
    .ToFuture<Order>(); 

// execute all three queries in one roundtrip 
var list = employee.ToList(); 
// get the first (and only) Employee in the list, NHibernate will have populated the Subordinates and Orders 
Employee empl = list.FirstOrDefault(); 

Gracias por marcar esto como la respuesta de todos modos.

+0

Hmm yo supongo que tendrá que esperar hasta que lo hacen para LINQ a continuación. Solo estoy usando 2 colecciones en este momento, así que estaría bien hasta que lo sacaran (realmente no estoy loco por las otras formas). – chobo2

+0

@ chobo2 he editado mi respuesta y proporciona una posible solución, trabajando para NHibernate.Linq –

+0

Si pudiera hacer +1 en esto dos veces que lo haría. Esto me acaba de salvar. *gracias*. –