Foreach循环不会遍历整个IEnumerable

时间:2016-04-08 15:16:19

标签: c# .net

我的foreach循环没有迭代整个集合,只是第一个元素,我无法弄清楚原因。我找到的唯一类似问题就是这个问题:IEnumerable not enumerating in foreach

但唯一的答案是由问题作者发布的,他谈到IEnumerable有一个暂停,这对我来说真的没有意义,我以前从未听说过。

IEnumerable<Document> documentsToAdd = dbEvent.Documents.Where(
    dbd => !eventToSave.Documents.Select(d => d.DocumentId)
    .Contains(dbd.DocumentId));
foreach (Document documentToAdd in documentsToAdd) {
    documentToAdd.DocumentType = null;
    documentToAdd.DeletedByUser = null;
    documentToAdd.DocumentOwnerTeam = null;
    documentToAdd.UploadedByUser = null;
    documentToAdd.UploadedInStage = null;
    hcDbContext.Documents.Add(documentToAdd);
}

在调试器中,我可以看到documentsToAdd在集合中有3个元素。但是当我逐步完成循环时,它只会经历一次然后继续前进,所以只保存第一个文档。由于我已经验证了documentsToAdd的内容,因此我知道问题不在Where子句中。为什么foreach不会浏览整个集合?

修改

要清楚,不会抛出任何异常。它会循环一次,然后转到foreach之后的下一行。

1 个答案:

答案 0 :(得分:2)

IEnumerable是一个迭代器,因此它一次返回一个结果。

每次foreach循环时,都会向迭代器询问下一个结果。有时结果可能会从枚举的集合中消失,因此您会遇到意外行为。

要避免这种情况,请确保在启动foreach之前获得所有结果,方法是调用.ToList()

  // Make a list of all documents
  List<Document> documentsToAdd;

  documentsToAdd = dbEvent.Documents
                          .Where(dbd => !eventToSave.Documents
                                                    .Select(d => d.DocumentId)
                                                    .Contains(dbd.DocumentId))
                          .ToList();   // load all results

  // Now this will loop through the whole list
  foreach (Document documentToAdd in documentsToAdd) 
  {
      documentToAdd.DocumentType = null;
      documentToAdd.DeletedByUser = null;
      documentToAdd.DocumentOwnerTeam = null;
      documentToAdd.UploadedByUser = null;
      documentToAdd.UploadedInStage = null;

      hcDbContext.Documents.Add(documentToAdd);
  }