我有一个小程序需要对数据范围进行一些计算。该范围可能包含大约半毫米的记录。我只是查看了我的数据库,发现group by
已被执行。
我认为结果是在第一行执行的,后来我只使用了RAM中的数据。但现在我认为查询构建器结合了表达式。
var Test = db.Test.Where(x => x > Date.Now.AddDays(-7));
var Test2 = (from p in Test
group p by p.CustomerId into g
select new { UniqueCount = g.Count() } );
在我的真实应用程序中,我得到了更多基于第一个查询所选范围的子查询。我想我只是增加了一个很大的开销,让DB做出不同的选择。
现在我只是在第一个表达式之后调用.ToList()
。
所以我的问题是我是否正确,查询构建器在构建表达式树时组合了不同的IQueryable?
答案 0 :(得分:4)
是的,你是对的。 LINQ表达式在您评估它们时会被懒惰地评估(例如,通过.ToList()
)。在那个时间点,实体框架将查看总查询并构建一个SQL语句来表示它。
在这种特殊情况下,不评估第一个查询可能更明智,因为SQL数据库已经过优化,可以执行基于集合的操作,如分组和计数。而不是强制数据库通过线路发送所有Test
对象,将结果反序列化为内存中对象,然后在本地执行分组和计数,通过让SQL数据库返回,您可能会看到更好的性能由此产生的计数。