2013-03-28 54 views
4

我对此有点新。好奇在以下情况会发生什么?LINQ to SQL推迟执行和实现

var q = //MY LINQ TO SQL QUERY.Select(...) 
......... 
......... 
var c = q.Count(); 
......... 
......... 
var x = q.Where(....).Select(....); 
var y = x.ToList();//or something such that forces materialization 
var d = q.Count();//same as c 
var e = x.Count(); 
var f = y.Count(); 

sql语句实际上有多少次访问数据库?一旦在Count()。再次在Where()?或者Linq保留Count()期间实现的内容?

或者它也取决于哪里(..)有什么?就像它再次引用数据库vs,它只是引用了作为'q'/或任何其他.net集合等的一部分获得的内容?

编辑:

更新我的代码以一对夫妇的其他情形。当你调用Count它并没有实现整个数据集

q -no db trip 
c -yes, but translates to aggregate qry - select Count(*) and not a result set (as per answer below) 
x -no db trip. No matter what is written in the Where(..) 
y - yes 
d - yes - does not *reuse* c 
e - yes - select count(*) EVEN THOUGH x already materized during y 
f - no db trip 

回答

4

:请纠正我下面的答案。相反,它准备并执行类似

SELECT COUNT(*) FROM ... 

使用ExecuteScalar得到结果的查询。

当你打电话WhereSelect它并没有实现任何东西(假设qIQueryable)。相反,它只是准备查询像

SELECT col1, col2, ... FROM ... 

但它实际上并没有在这一点上执行。它只会在q上致电GetEnumerator时执行查询。你很少直接做到这一点,但是像下面什么会导致执行查询:

var arry = q.ToArray(); 
var list = q.ToList(); 
foreach(var rec in q) ... 

它只会执行这个查询一次,所以有多个foreach循环不会创建多个数据库查询。当然,如果您基于q(例如var q2 = q.Where(...))创建新的IQueryable,它将不会绑定到q所使用的结果集,因此它必须再次查询数据库。

我在LINQPad中测试了你的代码,看起来你所有的分析都是正确的。