NHibernate的QueryOver与取导致多个SQL查询和数据库命中 [英] NHibernate QueryOver with Fetch resulting multiple sql queries and db hits

查看:241
本文介绍了NHibernate的QueryOver与取导致多个SQL查询和数据库命中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想选择一个实体,并获取相关的一个列表:

  Session.QueryOver<&UserRole的GT;()
           .Fetch(X => x.UsersInRole).Eager
           .LIST();

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


  SELECT ... FROM的UserRole
 左外连接UsersInRoles上...


和数百个独立的查询,看起来是这样的:


  SELECT ... FROM UsersInRoles
 左外连接上的UserRole ...
 WHERE UserRoles.UserId =?


的映射如下:

 公共类UserRoleMap:ClassMap<&UserRole的GT;
{
    公共UserRoleMap()
    {
        ID(X => x.Id);
        地图(X => x.RoleName);
        HasManyToMany(X => x.UsersInRole)
        。逆()
        .LazyLoad()
        。表(UsersInRoles);
    }
}


解决方案

我会说,这行为是我们应该期待什么。让我们有一种情况,其中我们在系统2的用户和2角色

 用户1  - 基于role1 //只有基于role1
用户2 - 基于role1 //现在我们看到,基于role2有更多的用户1,然后
用户2 - 基于role2

让我们说,这第一个查询,将只检索的用户1 的和它的许多一对多关系的基于role1 的。我们目前已经在的Isession 什么是唯一的用户1 的,所以对于组用户的基于role1 的是<强>不完整的 (我们不能重复使用装入的Isession此刻对象)的。但如何应该知道我们在哪里?这加载基于role1 所有数据是或不是会话?

新查询,装载了 role1上的数据必须发出。而这样一来,我们就可以在年底有这些疑问的dosens ...

我看到了什么是最好的解决方案(我在几乎所有情况下使用它)在批量大小设置:的 19.1.5。使用批量抓取

  HasManyToMany(X =&GT; x.UsersInRole)
  ...
  .BatchSize(25)

标记所有您的收藏地图.BatchSize(25)做,即使是类映射为好。这将导致更多的则1 SQL脚本,但最后的不可以更多然后1 +(2-4)取决于批量大小和页面大小。

I'm trying to select an entity and fetch a related list:

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

Which results in a lot of database hits. The first one is something like:

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

And hundreds more seperate queries which looks something like:

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

The mapping is as following:

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

解决方案

I would say, that this behaviour is what we should expect. Let's have a scenario, in which we have in the system 2 users and 2 roles

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

Let's say, that the first query, will retrieve only User1 and its many-to-many relation Role1. What we have in the ISession at the moment is only User1, so the set of Users for Role1 is incomplete (we cannot reuse objects loaded into ISession at the moment). But how should one know where we are? That all data loaded for Role1 is or is not in the session?

New query, loading the data for Role1 must be issued. And this way, we can at the end have dosens of these queries...

What I see as the best solution (I am using it in almost all scenarios) is the batch-size setting: 19.1.5. Using batch fetching

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

Mark all your collection maps with .BatchSize(25) and do that even for the Class map as well. That will cause more then 1 SQL Script, but at the end not more then 1 + (2-4) dependent on the batch-size and page size.

这篇关于NHibernate的QueryOver与取导致多个SQL查询和数据库命中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆