优化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。

优化NHibernate生成的SQL

当我创建查询并明确指定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中得到了修复(从昨天起就发布了预发布版本)