我试图执行一个简单的查询,它运行得很好,但是使用nhibernate profiler我发现它可以提供比它应该更多的查询。
我的实体:
资料:
GufBeProfile gufAlias = null;
HarshaaBeModule moduleAlias = null;
session.QueryOver<Profile>()
.JoinAlias(x => x.Gufim, () => gufAlias)
.JoinAlias(() => gufAlias.Harshaaot, () => moduleAlias)
.SingleOrDefault();
这是我的疑问:
{{1}}
在排除查询后,分析器显示了以下查询: - 使用两个连接从Profile表中获取。
使用AutoMapper将结果转换为DTO对象后,探查器会再显示2个查询: - 从GufBeProfile表中获取。 - 从HarshaaBeModule表中获取。
我认为加入阿里亚斯应该阻止它。
这是怎么回事?
答案 0 :(得分:0)
您尚未发布配置代码。你正在加载lazy
吗?
如果您正在使用xml映射,您是否正在执行以下操作?
<class name="A" table="A" lazy="true">
如果是这样,那就是NHibernate生成多个查询的原因。
NHibernate首先生成查询以从主表中获取所有行,而不从任何相关表中获取数据。然后,它为依赖表上的主键生成带有WHERE子句的新查询。然后,它将来自多个查询的输出映射到您的POCO或实体。
如果你想避免这种情况并要求NHibernate一次性检索数据,请尝试使用预先加载。使用.hbm文件,您可以通过设置lazy="false"
来实现相同目标。
另外(或者)在你的关联上设置获取机制,如下所示: -
<set name="PocoName" table="TableName" fetch="join">
我同意@DavidOsborne在评论中所说的话。
从他提到的link复制以下内容: -
相反,我们保留默认行为,并为a覆盖它 特定交易,使用
left join fetch
中的HQL
。这说明 NHibernate在第一个选择中急切地获取关联,使用 外连接。在ICriteria
查询API中,您可以使用SetFetchMode(FetchMode.Join)
。如果您觉得自己希望改变抓取策略 由
Get()
或Load()
使用,只需使用ICriteria
查询即可 例如:User user = (User) session.CreateCriteria<User>() .SetFetchMode("Permissions", FetchMode.Join) .Add( Expression.Eq("Id", userId) ) .UniqueResult();
避免N + 1选择问题的一种完全不同的方法是 使用二级缓存。