EF Core查询本地正常但生产环境报CheckDataIsReady错误求助
我编写了如下EF Core查询代码:
public async Task<List<RuleEvent>> GetEnabledRuleEventsAsync(string eventName) { return await _context.RuleEvents .Include(c => c.Rule) .Include(c => c.Event) .Where(c => c.Enabled && c.Rule.Enabled && c.Event.Name.ToLower().Trim() == eventName.ToLower().Trim()) .ToListAsync(); }
本地通过Visual Studio调试时该查询运行正常,但部署到生产环境后出现以下异常:
An exception occurred while iterating over the results of a query for
context type "ABCRepository.Entities.ABCContext".
System.InvalidOperationException: Invalid attempt to call
CheckDataIsReady when reader is closed.
ABCContext的配置方式如下:
services.AddDbContext<ABCContext>(option => option.UseSqlServer(connectionString), ServiceLifetime.Transient);
可能的解决方案
1. 启用SQL Server多活动结果集(MARS)
在生产环境的数据库连接字符串中添加MultipleActiveResultSets=True配置项,示例:
Server=你的服务器地址;Database=目标数据库名;User Id=账号;Password=密码;MultipleActiveResultSets=True;
当查询包含多个Include关联导航属性时,EF Core可能需要同时处理多个结果集,未启用MARS会导致数据阅读器提前关闭,触发该异常。
2. 调整DbContext生命周期
将DbContext的生命周期从Transient改为EF Core推荐的Scoped(适合Web应用场景):
services.AddDbContext<ABCContext>(option => option.UseSqlServer(connectionString), ServiceLifetime.Scoped);
Transient模式下,DI容器可能在异步查询完成前就回收了DbContext实例,导致关联的数据库连接被提前关闭。
3. 优化查询的字符串比较逻辑
避免在数据库端执行ToLower().Trim()这类字符串操作,可根据数据库排序规则调整查询:
// 若数据库使用不区分大小写的排序规则,可简化为: .Where(c => c.Enabled && c.Rule.Enabled && c.Event.Name.Trim() == eventName.Trim()) // 或使用EF Core内置的函数实现匹配: .Where(c => c.Enabled && c.Rule.Enabled && EF.Functions.Like(c.Event.Name.Trim(), eventName.Trim()))
减少数据库端的计算开销,避免因查询执行逻辑异常导致阅读器状态异常。
4. 检查生产环境数据库连接状态
确认生产环境的数据库连接字符串配置正确,应用程序拥有足够的数据库访问权限,同时排查数据库服务器是否存在连接池耗尽、负载过高导致连接提前断开的情况。
内容的提问来源于stack exchange,提问作者Aishwarya Shiva

