简体   繁体   English

将当前事务传递给DbCommand

[英]Pass current transaction to DbCommand

I'm working on a project using ASP.NET Core 2.1 and EF Core 2.1. 我正在使用ASP.NET Core 2.1和EF Core 2.1开发一个项目。 Although most of queries and commands use EF, some units needs to call stored procedures directly. 虽然大多数查询和命令都使用EF,但某些单元需要直接调用存储过程。

I can't use FromSql , because it needs results set based on entity models. 我不能使用FromSql ,因为它需要基于实体模型的结果集。

Let's assume we have these methods: 我们假设我们有这些方法:

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
    }
}

If I call both commands in one transaction like this: 如果我在一个事务中调用这两个命令,如下所示:

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

this exception will be happened: 这个例外将会发生:

BeginExecuteReader requires the command to have a transaction when the connection assigned to the command is in a pending local transaction. 当分配给命令的连接处于挂起的本地事务中时,BeginExecuteReader要求该命令具有事务。 The Transaction property of the command has not been initialized. 该命令的Transaction属性尚未初始化。

I have to mention, it's not as simple as command.Transaction = ... . 我不得不提一下,它不像command.Transaction = ...那么简单。 This requires DbTransaction which differs from the transaction EF uses. 这需要DbTransaction ,它与EF使用的事务不同。

I've stocked with this for a month! 我已经放了一个月了! Is there any workaround for this? 这有什么解决方法吗? Thank you so much. 非常感谢。

I have to mention, it's not as simple as command.Transaction = .... This requires DbTransaction which differs from the transaction EF uses. 我不得不提一下,它不像command.Transaction = ....这需要DbTransaction ,它与EF使用的事务不同。

Actually it is. 实际上是。 All you need is a reference to Microsoft.EntityFrameworkCore.Relational assembly and add 您只需要参考Microsoft.EntityFrameworkCore.Relational程序集并添加

using Microsoft.EntityFrameworkCore.Storage;

to get access to GetDbTransaction extension method: 访问GetDbTransaction扩展方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM