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

lit*_*rva 2 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 };
Run Code Online (Sandbox Code Playgroud)

存储库方法如下所示:

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

它似乎首先运行初始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个查询来获取地址.我在这里期待太多,还是我只是做错了什么?

安东尼

Jon*_*eet 6

更改GetCasesByProjectManagerID的声明:

public IQueryable<Case> GetCasesByProjectManagerID(int projectManagerId)
Run Code Online (Sandbox Code Playgroud)

你不能用以下方式撰写查询IEnumerable<T>- 它们只是序列.IQueryable<T>是专门为这样的组合而设计的.