c# - projections - session query nhibernate
NHibernate QueryOver con Fetch resulta en mĂșltiples consultas sql y hits de DB (1)
Yo diría que este comportamiento es lo que deberíamos esperar. Tengamos un escenario, en el cual tenemos en el sistema 2 usuarios y 2 roles
User1 - Role1 // has only Role1
User2 - Role1 // now we see that Role2 has more then User1
User2 - Role2
Digamos que la primera consulta recuperará solo el Usuario1 y su relación muchos a varios Role1 . Lo que tenemos en la ISession
en este momento es solo User1 , por lo que el conjunto de usuarios para Role1 está incompleto (no podemos reutilizar los objetos cargados en ISession en este momento) . Pero, ¿cómo se debe saber dónde estamos? ¿Que todos los datos cargados para Role1
están o no en la sesión?
Role1
debe emitir una nueva consulta, cargando los datos para Role1
. Y de esta manera, al final podemos tener dosens de estas consultas ...
Lo que veo como la mejor solución (lo estoy usando en casi todos los escenarios) es la configuración del batch-size
: 19.1.5. Utilizando la recuperación por lotes
HasManyToMany(x => x.UsersInRole)
...
.BatchSize(25)
Marque todos los mapas de su colección con .BatchSize(25)
y hágalo también para el mapa de la Clase. Eso causará más de 1 SQL Script, pero al final no más de 1 + (2-4) dependiendo del tamaño del lote y el tamaño de la página.
Estoy tratando de seleccionar una entidad y buscar una lista relacionada:
Session.QueryOver<UserRole>()
.Fetch(x => x.UsersInRole).Eager
.List();
Lo que resulta en una gran cantidad de visitas a la base de datos. El primero es algo así como:
SELECT ... FROM UserRoles left outer join UsersInRoles on ...
Y cientos de consultas separadas que se parecen a las siguientes:
SELECT ... FROM UsersInRoles left outer join UserRoles on ... WHERE UserRoles.UserId=?
El mapeo es el siguiente:
public class UserRoleMap : ClassMap<UserRole>
{
public UserRoleMap()
{
Id(x => x.Id);
Map(x => x.RoleName);
HasManyToMany(x => x.UsersInRole)
.Inverse()
.LazyLoad()
.Table("UsersInRoles");
}
}