将当前事务传递给 DbCommand

Pass current transaction to DbCommand

我正在使用 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 requires the command to have a transaction when the connection assigned to the command is in a pending local transaction. The Transaction property of the command has not been initialized.

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

我坚持了一个月!

有什么解决方法吗?

非常感谢。

I have to mention, it's not as simple as command.Transaction = .... This requires DbTransaction which differs from the transaction EF uses.

原来如此。您只需要引用 Microsoft.EntityFrameworkCore.Relational 程序集并添加

using Microsoft.EntityFrameworkCore.Storage;

访问 GetDbTransaction 扩展方法:

command.Transaction = context.Database.CurrentTransaction?.GetDbTransaction();