NHibernate QueryOver com Fetch resultando várias consultas SQL e ocorrências de db

Estou tentando selecionar uma entidade e buscar uma lista relacionada:

Session.QueryOver() .Fetch(x => x.UsersInRole).Eager .List(); 

Que resulta em muitos hits do database. O primeiro é algo como:

  SELECT ... FROM UserRoles left outer join UsersInRoles on ... 

E centenas de consultas separadas que se parecem com:

  SELECT ... FROM UsersInRoles left outer join UserRoles on ... WHERE UserRoles.UserId=? 

O mapeamento é o seguinte:

 public class UserRoleMap : ClassMap { public UserRoleMap() { Id(x => x.Id); Map(x => x.RoleName); HasManyToMany(x => x.UsersInRole) .Inverse() .LazyLoad() .Table("UsersInRoles"); } } 

Eu diria que esse comportamento é o que devemos esperar. Vamos ter um cenário, em que temos no sistema 2 usuários e 2 papéis

 User1 - Role1 // has only Role1 User2 - Role1 // now we see that Role2 has more then User1 User2 - Role2 

Digamos que a primeira consulta recuperará apenas o User1 e sua relação de muitos para muitos, Role1 . O que temos na ISession no momento é apenas User1 , então o conjunto de Usuários para Role1 está incompleto (não podemos reutilizar objects carregados em ISession no momento) . Mas como se deve saber onde estamos? Que todos os dados carregados para a Role1 estão ou não na session?

Nova consulta, carregando os dados para o Role1 deve ser emitida. E assim, podemos no final ter dosens dessas consultas …

O que eu vejo como a melhor solução (estou usando em quase todos os cenários) é a configuração de batch-size : 19.1.5. Usando a busca em lote

 HasManyToMany(x => x.UsersInRole) ... .BatchSize(25) 

Marque todos os seus mapas de coleção com .BatchSize(25) e faça isso também para o mapa de Classes. Isso fará com que mais de 1 SQL Script, mas no final não mais de 1 + (2-4) depende do tamanho do lote e tamanho da página.