LINQ到SQL延迟执行和物化

LINQ到SQL延迟执行和物化,linq,linq-to-sql,Linq,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();//sam

我对这有点陌生。好奇在下列情况下会发生什么

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语句实际访问数据库多少次?一次计数()。再次在Where()处?或者Linq保留在Count()期间实现的内容

或者这也取决于(…)的位置?比如,如果它再次引用数据库,而不是仅仅引用作为“q”或任何其他.net集合的一部分获得的内容,等等

编辑:

用几个其他场景更新了我的代码。请更正我以下的答案:

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

调用
Count
时,它不会具体化整个数据集。相反,它准备并执行一个查询,如

SELECT COUNT(*) FROM ...
使用
ExecuteScalar
获取结果

调用
Where
Select
时,它不会具体化任何内容(假设
q
IQueryable
)。相反,它只是准备一个查询,如

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中测试了您的代码,您的分析似乎都是正确的