foreach 迭代器是在循环之前触发一次还是每次触发?



对不起,如果我在标题上弄错了,

我想问的很容易通过下面的代码说出来;

var userList = context.Where(w=> w.age > 20);
foreach(var item in userList.ToList())
{
...
}

userList.ToList((检索 100 行

我想知道"userList.ToList(("是否触发了 100 次,(每次迭代并转到数据库检索记录(

或者只迭代一次原始集合。

这看起来很奇怪,但现在对我来说非常重要,因为我的同事声称它敲到 db 100 次,我相信它确实有一次......

它会调用数据库一次,你甚至不需要ToList。检查它的最简单方法 - 只需使用数据库分析器并查看将命中的查询。 编译器将foreach转换为类似的东西:

IEnumerator<EntityType> enumerator = queryable.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
EntityType current = enumerator.Current;
}
}
finally
{
if (enumerator != null)
{
enumerator.Dispose();
}
}

因此,您正在使用相同的Enumerator并且多次调用 db 是没有意义的。

另外,如果你的同事关于userList.ToList()被解雇100次的声明,下一个应该多次写信给控制台:

IEnumerable<int> GetEn()
{
Console.WriteLine(nameof(GetEn));
foreach (var element in new[] {10,20,30})
{
yield return element;
}
}
var userList = GetEn().Where(w => w > 20);  
foreach (var item in userList.ToList())
{

}

最新更新