【问题标题】:On Accessing DbContext , I get System.ObjectDisposedException: 'Cannot access a disposed object在访问 DbContext 时,我得到 System.ObjectDisposedException: \'Cannot access a disposed object
【发布时间】:2023-01-18 23:02:19
【问题描述】:

我正在写这段代码:

var pOrders =   await _dbContext.POrders.Where(x => x.ShipId == data.shipNumber).ToListAsync();
                pOrders.ForEach(async po =>
                {
                    var cardProcess =  await _dbContext.CardProcesses.FirstOrDefaultAsync(x => po.Id == x.PurchaseOrderId);
                    cardProcess.SettleStatus = ViewModels.SettleStatus.NA.ToString();
              
                    var shipId = po.ShipId;
                    var taskFile = await _dbContext.TaskFiles.FirstOrDefaultAsync(x => x.ShipNumber == shipId);
                    var taskFileId = taskFile.Id;
                    var taskFilesExt = await _dbContext.TaskFileExts.FirstOrDefaultAsync(x => x.JobFileId == taskFileId);
                    if (taskFilesExt != null)
                    {
                        taskFilesExt.SettlStatus = NA.ToString();

                        taskFilesExt.SettleStatus_NA +=  1 ;

                        jtaskFilesExt.SettleStatus_NA -= model.OldStatus.ToString() == NA.ToString() ? 1 : 0;
                        taskFilesExt.SettleStatus_Audited -= model.OldStatus.ToString() == Audited.ToString() ? 1 : 0;
                        taskFilesExt.SettlStatus_ReadyToPay -= model.OldStatus.ToString() == ReadyToPay.ToString() ? 1 : 0;
                    }
                });

但是当我尝试在第 4 行访问 dbContext 时出现此错误:

System.ObjectDisposedException: 'Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application

我一直试图纠正这个问题但没有成功。我哪里错了?

【问题讨论】:

  • 没有完整的例子很难说。许多 ForEach 扩展方法(我们不知道你在使用什么)不能很好地处理异步 lambdas 而那些我希望返回一些东西的 awaitable - 所以要么你只是错过了一个 @编译器应该标记的 987654325@ 或者你不应该使用那个 ForEach 方法。
  • _dbContext 来自哪里?错误消息解释了此错误的一个可能原因。其余代码也有问题 - 不是使用 EF Core 在单个操作中加载相关订单和所有相关的CardProcessTaskFiles 等,而是使用单独的连接和查询一个一个地加载它们每一次。这是加载数据的最慢方式。这叫做RBAR - Row-By-Agonizing-Row
  • @PanagiotisKanavos 我正在为 dbcontext 使用依赖注入
  • @sapter 你在哪里使用它?您不会在控制器操作中遇到这样的错误,因为 DI 会为每个请求创建一个新实例。如果将 DbContext 存储在静态字段中并尝试重用它,就会出现该错误。如果您尝试在 BackgroundService 中使用作用域 DbContext,您也会收到该错误
  • 您不能将 ForEach 与异步 lambda 一起使用。请改用foreach

标签: c# linq .net-core dependency-injection


【解决方案1】:

List.ForEach 的问题它不是为异步执行而设计的。它不是初始化对象,而是创建在后台执行的任务。这导致在所有任务完成之前处理该上下文。

只需替换为foreach

var pOrders = await _dbContext.POrders.Where(x => x.ShipId == data.shipNumber).ToListAsync();

foreach (var po in pOrders)
{
    var cardProcess =  await _dbContext.CardProcesses.FirstOrDefaultAsync(x => po.Id == x.PurchaseOrderId);
    ....
};

【讨论】:

  • 当我使用 forEach 时,它说 List<> 不包含“forEach”的定义....我通过在循环内的 dbContext 调用前面删除 await 来解决错误。
  • 怎么可能? foreachIEnumerable 的标准 C# 语句。你解决错了。
猜你喜欢
  • 2015-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-11
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
相关资源
最近更新 更多