5

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

    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");
    }
}
4

1 回答 1

3

我会说,这种行为是我们应该期待的。让我们有一个场景,其中我们在系统中有 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),具体取决于批处理大小和页面大小。

于 2013-10-10T04:21:49.147 回答