2013-03-28 55 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中測試了你的代碼,看起來你所有的分析都是正確的。