优化NHibernate生成的SQL
本文关键字:SQL NHibernate 优化 | 更新日期: 2023-09-27 18:27:25
我有一个NHibernate LINQ查询,如下所示:
var maxNumber = session
.Linq<Child>()
.Where(c => c.Parent == parent)
.Max(c => c.Number);
NHibernate生成以下SQL:
SELECT max(this_.Number)
FROM [Child] as this_
LEFT OUTER JOIN [Parent] parent1_
ON this_.Parent_id = parent1_.Id
WHERE parent1_.Id = @p0
我希望它能简单地生成这样的东西:
SELECT max(this_.Number)
FROM [Child] as this_
WHERE this_.Parent_id = @p0
我本以为两个查询的执行计划会完全相同,但事实并非如此。
我的实体定义如下:
class Parent
{
long Id { get; set; }
string Name { get; set; }
}
class Child
{
long Id { get; set; }
int Number { get; set; }
Parent Parent { get; set; } // mapped as FK
}
使用这样的映射:
class ParentMap : ClassMap<Parent>
{
public ParentMap()
{
Id(x => x.Id).GeneratedBy.Increment();
Map(x => x.Name);
}
}
class ChildMap : ClassMap<Child>
{
public ChildMap()
{
Id(x => x.Id).GeneratedBy.Increment();
Map(x => x.Number);
References(x => x.Parent);
}
}
如何使用NHibernate重写它以获得后一个输出?这是在存储库方法中完成的,所以如果需要的话,我可以很容易地切换到HQL或其他东西(当然,如果其他一切都失败了,也可以切换到普通的DbCommand
)。
我正在使用NHibernate 2.0与LINQ to NHibernat和SQL Server 2008 R2。
当我创建查询并明确指定Id时,它是我要查询的属性,而不是我得到"优化"查询的实体。即:
session
.Query<Child>()
.Where(c => c.Parent.Id = parent.Id)
.Max(c = c.Number);
如果使用Query<>
,则不能使用NHibernate 2.0。
假设这是一个拼写错误,而您的意思是3.0,请尝试更新到3.2。我刚刚验证了您的查询完全符合预期。
现在,在3.2中有一个错误,如果你这样写查询,它会导致额外的联接:
var maxNumber = session
.Query<Child>()
.Where(c => c.Parent.Id == parent.Id)
.Max(c => c.Number);
这在3.3中得到了修复(从昨天起就发布了预发布版本)