我们有一个Web应用程序,它使用Entity框架来访问数据(db是Oracle)。我们最近搬到了EF6。 我们以下列方式使用交易:
EntityTransaction
个对象和EntityConnection
对象。ObjectContext
对象创建自己的EntityConnection
。事务请求部分并行运行,因此在给定的时刻,并行运行请求很少。在这些情况下,奇怪的错误开始发生:
例外 - Collection was modified; enumeration operation may not execute
。
在读取或更新数据时,甚至在访问EntityTransaction的Connection属性时都会发生这种情况。
堆栈跟踪的开始可能会有所不同,但结尾总是相同的:
System.InvalidOperationException:修改了集合;枚举操作可能无法执行。 在System.Collections.Generic.List
1.Enumerator.MoveNextRare() at System.Linq.Enumerable.WhereSelectListIterator
2.MoveNext() 在System.Linq.Enumerable.d__142.MoveNext() at System.Linq.Enumerable.<DistinctIterator>d__81
1.MoveNext() 在System.Linq.Enumerable.WhereEnumerableIterator1.MoveNext() at System.Collections.Generic.List
1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable
1 source) 在System.Data.Entity.Infrastructure.Interception.DbInterceptionContext..ctor(IEnumerable`1 copyFrom) 在System.Data.Entity.Core.EntityClient.EntityTransaction.get_InterceptionContext()
实际上堆栈跟踪结束还有另一种变体(但是你可以看到它们基本相同):
System.InvalidOperationException:修改了集合;枚举操作可能无法执行。 在System.Collections.Generic.List
1.Enumerator.MoveNextRare() at System.Linq.Enumerable.WhereSelectListIterator
2.MoveNext() 在System.Linq.Enumerable.Any [TSource](IEnumerable1 source, Func
2谓词) 在System.Data.Entity.Infrastructure.Interception.DbInterceptionContext..ctor(IEnumerable`1 copyFrom) 在System.Data.Entity.Core.EntityClient.EntityConnection.get_InterceptionContext()
正如我们所看到的,错误发生在DbInterceptionContext
构造函数中。
它是一种EF内部结构,并且该集合(已修改)是一个内部集合,并且没有直接链接到我们的自定义代码。
很少注意到:
出现此错误的原因是什么?这是EF6的问题吗?
或者我们以错误的方式使用EF?
是否允许为一个应该同时运行的连接创建多个ObjectContext
- ?
如果需要,我可以提供完整调用堆栈的一些示例。
答案 0 :(得分:2)
如果在迭代时对集合添加/删除,则会出现此问题:
// throws "collection was modified" error
foreach (var item in myCollection) {
myCollection.Remove(item);
}
// to fix this problem, iterate over a copy of the collection whose count does not change
var fixedSize = myCollection.ToArray();
foreach (var item in fixedSize) {
myCollection.Remove(item);
}
也许您的旧代码返回数组,而EF 6代码返回IEnumerable?您应该检查您的创建/更新/删除用例以解决此问题。