Linq to NHibernate在一个请求中生成3,000多个SQL语句!

时间:2009-07-22 16:02:55

标签: linq nhibernate linq-to-nhibernate

过去几个月我一直在使用Linq到NHibernate开发一个webapp,但是直到现在还没有描述它生成的SQL。使用NH Profiler,现在看来,当执行Linq表达式时,下面的代码块会使DB超过3,000次。

        var activeCaseList = from c in UserRepository.GetCasesByProjectManagerID(consultantId)
                             where c.CompletionDate == null
                             select new { c.PropertyID, c.Reference, c.Property.Address, DaysOld = DateTime.Now.Subtract(c.CreationDate).Days, JobValue = String.Format("£{0:0,0}", c.JobValue), c.CurrentStatus };

Repository方法的样子:

    public IEnumerable<Case> GetCasesByProjectManagerID(int projectManagerId)
    {
        return from c in Session.Linq<Case>()
               where c.ProjectManagerID == projectManagerId
               select c;
    }

它似乎首先运行初始Repository查询,然后遍历所有结果检查以查看CompletionDate是否为null,但是发出查询以首先获取c.Property.Address。

因此,如果初始查询返回2,000条记录,即使其中只有五条没有CompletionDate,它仍然会触发SQL查询以恢复2,000条记录的地址详细信息。

我想象的方式可行,是它会评估所有WHERE和SELECT子句并简单地合并它们,因此初始查询将如下:

SELECT ... WHERE ProjectManager = @ p1 AND CompleteDate IS NOT NULL

哪个会产生5条记录,然后它可以触发另外5条查询以获取地址。我在这里期待太多,或者我只是做错了什么?

安东尼

2 个答案:

答案 0 :(得分:6)

更改GetCasesByProjectManagerID的声明:

public IQueryable<Case> GetCasesByProjectManagerID(int projectManagerId)

您无法使用IEnumerable<T>撰写查询 - 它们只是序列。 IQueryable<T>专为此类作文设计。

答案 1 :(得分:0)

由于我还不能添加评论。 Jon Skeet是对的,你想要使用IQueryable,这是允许Linq提供者来Lazily构造SQL。 IEnumerable是渴望的版本。