nhibernate - queryover join
¿Trae ansiosamente múltiples propiedades de colección(usando QueryOver/Linq)? (2)
Prefiero usar el proveedor de linq si es posible, especialmente si está utilizando versiones más nuevas de nhibernate (> = 4.0). Siempre y cuando tenga sus colecciones mapeadas como ISets (requiere .net framework> = 4) que convertimos para que podamos hacer una carga ansiosa y evitar productos cartesianos. Siento que esto no es algo que se anuncie mucho, pero prefiero este método cuando sea aplicable sobre cualquier otra cosa:
public class Person
{
public virtual int Id { get; private set; }
public virtual ISet<Book> Books { get; set; }
public virtual ISet<Article> Articles { get; set; }
public virtual ISet<Address> Addresses { get; set; }
}
public Person()
{
this.Books = new HashSet<Book>();
this.Articles = new HashSet<Article>();
this.Addresses = new HashSet<Address>();
}
Si tiene sus colecciones definidas como las anteriores, puede hacer lo siguiente y evitar problemas con productos cartesianos:
var persons = session.Query<Person>()
.FetchMany(x => x.Books)
.FetchMany(x => x.Articles)
.FetchMany(x => x.Addresses)
.ToList();
Encontré 2 preguntas similares:
- Múltiples búsquedas en linq to nhibernate
- ¿Es esta la forma correcta de usar ThenFetch () para cargar varias colecciones?
De acuerdo con esta página :
Tenga cuidado de no buscar ansiosamente varias propiedades de colección al mismo tiempo. Aunque esta declaración funcionará bien:
var employees = session.Query<Employee>() .Fetch(e => e.Subordinates) .Fetch(e => e.Orders).ToList();
Ejecuta una consulta de producto cartesiano en la base de datos, por lo que la cantidad total de filas devueltas será el total de Subordinados multiplicado por el total de pedidos.
Digamos que tengo el siguiente modelo:
public class Person
{
public virtual int Id { get; private set; }
public virtual ICollection<Book> Books { get; set; }
public virtual ICollection<Article> Articles { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
}
¿Cuál es la forma más sencilla de cargar ansiosamente a todas las personas con sus libros, artículos y direcciones utilizando QueryOver / Linq (sin devolver un producto cartesiano)?
Gracias
Actualizar:
Ver la answer cremor continuación y la answer Florian Lim en este hilo . El siguiente código funciona bien, solo un viaje de ida y vuelta a la base de datos.
var persons = session.QueryOver<Person>()
.Future<Person>();
var persons2 = session.QueryOver<Person>()
.Fetch(x => x.Books).Eager
.Future<Person>();
var persons3 = session.QueryOver<Person>()
.Fetch(x => x.Articles).Eager
.Future<Person>();
var persons4 = session.QueryOver<Person>()
.Fetch(x => x.Addresses).Eager
.Future<Person>();
public IList<Person> GetAll()
{
var persons = session.QueryOver<Person>()
.Future<Person>();
session.QueryOver<Person>()
.Fetch(x => x.Books).Eager
.Future<Person>();
session.QueryOver<Person>()
.Fetch(x => x.Articles).Eager
.Future<Person>();
session.QueryOver<Person>()
.Fetch(x => x.Addresses).Eager
.Future<Person>();
return persons.ToList();
}