Nhibernate - QueryOver尽管加入了取实体

时间:2016-11-06 14:20:25

标签: c# nhibernate automapper queryover

我试图执行一个简单的查询,它运行得很好,但是使用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表中获取。

我认为加入阿里亚斯应该阻止它。

这是怎么回事?

1 个答案:

答案 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">

更新1:

我同意@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选择问题的一种完全不同的方法是   使用二级缓存。