【问题标题】:Does foreach iterators fires once before the loop or each time? [duplicate]foreach 迭代器是在循环之前触发一次还是每次触发一次? [复制]
【发布时间】:2020-06-24 08:31:02
【问题描述】:

对不起,如果我在标题中解释错误,

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

var userList = context.Where(w=> w.age > 20);

foreach(var item in userList.ToList())
{
  ...
}

userList.ToList() 检索 100 行

我想知道 'userList.ToList()' 是否会触发 100 次,(每次迭代并去数据库检索记录)

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

这似乎很奇怪,但现在对我来说非常重要,因为我的同事声称它敲击 db 100 次,我相信它会敲一次..

【问题讨论】:

    标签: asp.net entity-framework


    【解决方案1】:

    它会调用数据库一次,你甚至不需要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())
    {
        
    }
    

    【讨论】:

      猜你喜欢
      • 2013-05-17
      • 1970-01-01
      • 2011-09-20
      • 1970-01-01
      • 2015-10-20
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多