NHibernate QueryOver与Fetch导致多个sql查询和数据库命中

本文关键字:查询 sql 数据库 QueryOver Fetch NHibernate | 更新日期: 2023-09-27 18:34:51

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

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

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

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

还有数百个单独的查询,如下所示:

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

映射如下:

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

NHibernate QueryOver与Fetch导致多个sql查询和数据库命中

我想

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

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

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

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

我认为最好的解决方案(我几乎在所有情况下都使用它(是batch-size设置:19.1.5。使用批量提取

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

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