首页 新闻 搜索 专区 学院

EF Core 为什么会抛出异常: Collection was modified; enumeration operation may not execute ?

0
悬赏园豆:200 [待解决问题]

我有一个 BlogPost 类,我写了一个用来分页读取的方法,如下:

var postQuery = _dbContext.Set<Entities.BlogPost>()
    .AsNoTracking()
    .Where(p => p.OwnerId == OwnerId && p.IsValid);
var list = await postQuery.OrderByDescending(p => p.DateAdded)
    .Skip(( index - 1 ) * size)
    .Take(size)
    .ToListAsync();

这段代码单独运行的时候基本没有发现问题,但是当我并行的执行 UI 自动化测试的时候,他就会抛出下面的异常:

An exception occurred while iterating over the results of a query for context type 'BlogDbContext'.
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.Collections.Generic.Dictionary`2.Enumerator.MoveNext()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.ToList()
   at Microsoft.EntityFrameworkCore.Query.Expressions.SelectExpression.PushDownSubquery()
   at Microsoft.EntityFrameworkCore.SqlServer.Query.Sql.Internal.SqlServerQuerySqlGenerator.RowNumberPagingExpressionVisitor.VisitSelectExpression(SelectExpression selectExpression)
   at Microsoft.EntityFrameworkCore.SqlServer.Query.Sql.Internal.SqlServerQuerySqlGeneratorFactory.CreateDefault(SelectExpression selectExpression)
   at Microsoft.EntityFrameworkCore.Query.Internal.ShaperCommandContext.GetRelationalCommand(IReadOnlyDictionary`2 parameters)
   at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.BufferlessMoveNext(DbContext _, Boolean buffer, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNext(CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)

EF Core 版本为 2.2.4。请问为什么会出现“集合被修改”这样的异常呢?

问题补充:

排查发现是 UseRowNumberForPaging 导致的问题,去掉 UseRowNumberForPaging 后这个问题就消失了。那 UseRowNumberForPaging 有替代方案吗?

不如隐茶去的主页 不如隐茶去 | 小虾三级 | 园豆:549
提问于:2019-05-09 10:35

并行操作是怎样的?是每一页都同时去获取数据吗

Shendu.CC 1年前

@Shendu.CC: 就是浏览器同时打开了多个页面而已,其中有读取数据的,也有修改数据的操作。

不如隐茶去 1年前
< >
分享
所有回答(2)
0

代码没毛病,修改数据的代码发来瞧瞧

Jeffcky | 园豆:2563 (老鸟四级) | 2019-05-09 13:31

修改数据的地方可就太多了,大多是很直接的使用 EF Ext 的 UpdateAsync 进行操作的。相关链接: https://entityframework-extensions.net/update-from-query

支持(0) 反对(0) 不如隐茶去 | 园豆:549 (小虾三级) | 2019-05-09 13:53

@不如隐茶去: 哦,更新数据查询出来有没有ToList()啊

支持(0) 反对(0) Jeffcky | 园豆:2563 (老鸟四级) | 2019-05-09 13:55

@Jeffcky: 更新数据的时候没有查询操作,所有的查询操作都用了 ToListAsync()

支持(0) 反对(0) 不如隐茶去 | 园豆:549 (小虾三级) | 2019-05-09 14:15
0

RowNumberPagingExpressionVisitor 的实现代码在这里,我觉得是 UseRowNumberForPaging 本身问题的可能性比较小,可能是应用的问题触发了这个表现

dudu | 园豆:38820 (高人七级) | 2019-05-09 17:26

在并发时会使用 LINQ query translation cache

支持(0) 反对(0) dudu | 园豆:38820 (高人七级) | 2019-05-09 17:31
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册