我对此有点新鲜。好奇在以下情况会发生什么?
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()期间实现的内容?
或者它还取决于Where(..)有什么?就像它再次引用数据库而它只是引用作为'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
答案 0 :(得分:4)
当您致电Count
时,它并未实现整个数据集。而是准备并执行像
SELECT COUNT(*) FROM ...
使用ExecuteScalar
获取结果。
当您致电Where
和Select
时,它没有实现任何内容(假设q
是IQueryable
)。相反,它只是准备一个像
SELECT col1, col2, ... FROM ...
但它实际上并没有在那时执行它。它只会在GetEnumerator
上调用q
时执行查询。您很少直接这样做,但以下任何内容都会导致您的查询被执行:
var arry = q.ToArray();
var list = q.ToList();
foreach(var rec in q) ...
它只会执行此查询一次,因此拥有多个foreach
循环不会创建多个数据库查询。当然,如果您基于IQueryable
创建新的q
(例如var q2 = q.Where(...)
),则不会绑定q
使用的结果集,因此必须再次查询数据库。
我在LINQPad中测试了你的代码,似乎所有的分析都是正确的。