我一直在外地得到这个例外。我不明白如何在迭代时修改集合。我在方法的开头将所有内容复制到局部变量。
public void Flush() {
var tempEntities = attachedEntities.Select(item => item).ToList();
attachedEntities.Clear();
var tempEntitiesToDelete = entitiesToDelete.Select(item => item).ToList();
entitiesToDelete.Clear();
foreach (var attachedEntity in tempEntities) {
var isTransient = (bool)GetPrivateField(attachedEntity.GetType(), attachedEntity, "isTransient");
if (isTransient)
db.Insert(attachedEntity);
else
db.Update(attachedEntity);
}
foreach (var entity in tempEntitiesToDelete)
db.Delete(entity);
}
堆栈跟踪
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.Collections.Generic.List`1 Enumerator[Compass.Mobile.Core.DataAccess.IEntity].VerifyState () [0x00000] in <filename unknown>:0
at System.Collections.Generic.List`1 Enumerator[Compass.Mobile.Core.DataAccess.IEntity].MoveNext () [0x00000] in <filename unknown>:0
at System.Linq.Enumerable <CreateSelectIterator>c__Iterator1D`2[Compass.Mobile.Core.DataAccess.IEntity,Compass.Mobile.Core.DataAccess.IEntity].MoveNext () [0x00000] in <filename unknown>:0
at System.Collections.Generic.List`1[Compass.Mobile.Core.DataAccess.IEntity].AddEnumerable (IEnumerable`1 enumerable) [0x00000] in <filename unknown>:0
at System.Collections.Generic.List`1[Compass.Mobile.Core.DataAccess.IEntity]..ctor (IEnumerable`1 collection) [0x00000] in <filename unknown>:0
at System.Linq.Enumerable.ToList[TSource] (IEnumerable`1 source) [0x00000] in <filename unknown>:0
at Compass.Mobile.Core.DataAccess.Session.Flush () [0x00000] in <filename unknown>:0
at Compass.Mobile.Core.DataAccess.Session.Commit () [0x00000] in <filename unknown>:0
at Compass.Mobile.Core.Bootstrap.CommandBus.Flush () [0x00000] in <filename unknown>:0
答案 0 :(得分:3)
替换它:
foreach (var entity in tempEntitiesToDelete)
db.Delete(entity);
使用:
for (var i = tempEntitiesToDelete.Count - 1; i >= 0; i--)
db.Delete(tempEntitiesToDelete[i]);
当我尝试在循环播放时删除时出现此问题;它试图修改项目列表。因此,向后循环修复它对我来说。
答案 1 :(得分:2)
根据堆栈跟踪判断,foreach
(或枚举tempEntities
这是一个普通列表)内部没有失败,但在ToList
次调用之内Select
迭代器的基础列表在继续下一个项目之前检查其状态。
堆栈跟踪中的这一行让我相信:
at System.Linq.Enumerable <CreateSelectIterator>c__Iterator1D`2[Compass.Mobile.Core.DataAccess.IEntity,Compass.Mobile.Core.DataAccess.IEntity].MoveNext () [0x00000] in <filename unknown>:0
您的foreach循环变量只是一个列表,因此它不会通过Select
。这让我相信attachedEntities
或entitiesToDelete
在您Select
之上发生变化时会发生变化:
/* Failing here... */
var tempEntities = attachedEntities.Select(item => item).ToList();
attachedEntities.Clear();
/* ...or here*/
var tempEntitiesToDelete = entitiesToDelete.Select(item => item).ToList();
entitiesToDelete.Clear();
/* ...but not here! */
foreach (var attachedEntity in tempEntities) {
// ...
}
很可能是并发问题。
顺便说一下,你真的不需要Select (item => item)
,它只是一个身份投射。