【问题标题】:Pass current transaction to DbCommand将当前事务传递给 DbCommand
【发布时间】:2018-09-16 09:11:36
【问题描述】:

我正在开发一个使用 ASP.NET Core 2.1 和 EF Core 2.1 的项目。虽然大部分查询和命令都使用EF,但有些单元需要直接调用存储过程。

我不能使用FromSql,因为它需要基于实体模型的结果集。

假设我们有这些方法:

public Task CommandOne(DbContext context)
{
    Entity entity = new Entity
    {
        Name = "Name"
    };
    context.DbSet<Entity>().Add(entity);
    return context.SaveChangesAsync();
}

public async Task CommandTwo(DbContext context)
{
    DbCommand command = context.Database.GetDbConnection().CreateCommand();
    command.CommandText = "storedProcName";
    command.CommandType = System.Data.CommandType.StoredProcedure;

    using (var reader = await command.ExecuteReaderAsync().ConfigureAwait(false))
    {
        // read result sets
    }
}

如果我像这样在一个事务中调用两个命令:

public async Task UnitOfWork(DbContext dbContext)
{
    using (var transaction = await dbContext.Database.BeginTransactionAsync())
    {
        await CommandOne(dbContext);
        await CommandTwo(dbContext);
    }
}

这个异常会发生:

BeginExecuteReader 要求命令有一个事务,当 分配给命令的连接处于挂起的本地事务中。 该命令的 Transaction 属性尚未初始化。

不得不提,它可不像command.Transaction = ...那么简单。这需要DbTransaction,这与 EF 使用的事务不同。

我已经囤了一个月了! 有什么解决方法吗? 非常感谢。

【问题讨论】:

  • 你在哪里将交易标记为完成transaction.Complete()
  • @Eldho 在交易范围关闭之前

标签: c# asp.net-core-mvc ef-core-2.1


【解决方案1】:

不得不提,它不像command.Transaction = ....那么简单,这需要DbTransaction,这与EF使用的事务不同。

其实是这样的。您只需要参考 Microsoft.EntityFrameworkCore.Relational 程序集并添加

using Microsoft.EntityFrameworkCore.Storage;

访问GetDbTransaction扩展方法:

if (context.Database.CurrentTransaction != null)
    command.Transaction = context.Database.CurrentTransaction.GetDbTransaction();

【讨论】:

    猜你喜欢
    • 2013-03-08
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多