带有Fetch的NHibernate QueryOver导致多个sql查询和db命中

Ada*_*Tal 5 c# sql nhibernate fetch queryover

我正在尝试选择一个实体并获取相关列表:

    Session.QueryOver<UserRole>()
           .Fetch(x => x.UsersInRole).Eager
           .List();
Run Code Online (Sandbox Code Playgroud)

这导致了大量的数据库命中.第一个是这样的:

 SELECT ... FROM UserRoles
 left outer join UsersInRoles on ...
Run Code Online (Sandbox Code Playgroud)

还有数百个单独的查询,看起来像:

 SELECT ... FROM UsersInRoles
 left outer join UserRoles on ...
 WHERE UserRoles.UserId=?
Run Code Online (Sandbox Code Playgroud)

映射如下:

public class UserRoleMap : ClassMap<UserRole>
{
    public UserRoleMap()
    {
        Id(x => x.Id);
        Map(x => x.RoleName);
        HasManyToMany(x => x.UsersInRole)
        .Inverse()
        .LazyLoad()
        .Table("UsersInRoles");
    }
}
Run Code Online (Sandbox Code Playgroud)

Rad*_*ler 3

我想说,这种行为是我们应该期待的。让我们有一个场景,系统中有 2 个用户和 2 个角色

User1 - Role1 // has only Role1
User2 - Role1 // now we see that Role2 has more then User1
User2 - Role2
Run Code Online (Sandbox Code Playgroud)

假设第一个查询将仅检索User1及其多对多关系Role1ISession目前我们只有User1 ,因此Role1的 Users 集是不完整的 (目前我们无法重用加载到 ISession 中的对象)。但人们如何知道我们在哪里呢?加载的所有数据Role1是否在会话中?

Role1必须发出新查询,加载数据。这样,我们最终就可以得到这些查询的信息......

我认为最好的解决方案(我在几乎所有场景中都使用它)是设置batch-size19.1.5。使用批量抓取

HasManyToMany(x => x.UsersInRole)
  ...
  .BatchSize(25)
Run Code Online (Sandbox Code Playgroud)

标记所有集合映射,.BatchSize(25)甚至对类映射也执行此操作。这将导致超过 1 个 SQL 脚本,但最终不会超过 1 + (2-4),具体取决于批处理大小和页面大小。