You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 8 Web API中EF Core 8 ExecuteUpdateAsync报错求助

问题分析与解决方案

报错This SqlTransaction has completed; it is no longer usable本质是EF Core尝试使用已完成(提交/回滚)或失效的事务执行更新操作,常见触发原因包括:

  • DbContext实例已被释放(比如生命周期管理错误)
  • 外部事务提前完成但代码仍在使用上下文
  • 查询条件中的空值(如toUpdateMailList为null)导致查询失败,触发事务异常终止

修复后的代码示例

基础修复:处理空值+确保上下文有效性

private async Task DemoUpdateTestTable(DemoReq demoReq, IEnumerable<string>? toUpdateMailList, CancellationToken cancellationToken)
{
    // 提前处理空值,避免Contains引发异常导致事务失效
    if (toUpdateMailList == null || !toUpdateMailList.Any())
        return;

    // 确认DbContext是Scoped注入(ASP.NET Core默认),确保在当前请求周期内有效
    await _demoDbContext.TestTable
        .Where(recordsToUpdate => toUpdateMailList.Contains(recordsToUpdate.EmailAddress) 
                                  && recordsToUpdate.Id == demoReq.Id)
        .ExecuteUpdateAsync(setters => setters
            .SetProperty(r => r.ModifyUserId, demoReq.CreateUserId)
            .SetProperty(r => r.ModifyDate, demoReq.ModifyDate)
            .SetProperty(r => r.IsApproved, r => !r.IsApproved ? null : (bool?)null),
        cancellationToken);
}

显式事务管理(适用于需要多操作原子性的场景)

如果该方法需要和其他数据库操作共享事务,显式控制事务生命周期:

private async Task DemoUpdateTestTable(DemoReq demoReq, IEnumerable<string>? toUpdateMailList, CancellationToken cancellationToken)
{
    if (toUpdateMailList == null || !toUpdateMailList.Any())
        return;

    using var transaction = await _demoDbContext.Database.BeginTransactionAsync(cancellationToken);
    try
    {
        await _demoDbContext.TestTable
            .Where(recordsToUpdate => toUpdateMailList.Contains(recordsToUpdate.EmailAddress) 
                                      && recordsToUpdate.Id == demoReq.Id)
            .ExecuteUpdateAsync(setters => setters
                .SetProperty(r => r.ModifyUserId, demoReq.CreateUserId)
                .SetProperty(r => r.ModifyDate, demoReq.ModifyDate)
                .SetProperty(r => r.IsApproved, r => !r.IsApproved ? null : (bool?)null),
            cancellationToken);

        // 若有其他数据库操作,在此添加

        await transaction.CommitAsync(cancellationToken);
    }
    catch
    {
        await transaction.RollbackAsync(cancellationToken);
        throw; // 重新抛出异常让上层处理
    }
}

额外注意事项

  • 确保_demoDbContext是通过ASP.NET Core的依赖注入系统注入的Scoped实例(避免Singleton导致的上下文复用问题)
  • 检查调用该方法的上层代码是否存在提前释放DbContext或终止事务的逻辑
  • 对于IsApproved的赋值逻辑,可以简化为r => r.IsApproved ? null : (bool?)null(逻辑等价,更简洁)

内容的提问来源于stack exchange,提问作者santosh kumar patro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:47:16