Передать текущую транзакцию в DbCommand - PullRequest
0 голосов
/ 16 сентября 2018

Я работаю над проектом, использующим 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.

Я запасался этим уже месяц!Есть ли обходной путь для этого?Большое вам спасибо.

1 Ответ

0 голосов
/ 16 сентября 2018

Я должен отметить, что это не так просто, как command.Transaction = .... Это требует DbTransaction, что отличается от транзакции, используемой EF.

На самом деле это так.Все, что вам нужно, это ссылка на Microsoft.EntityFrameworkCore.Relational сборка и добавить

using Microsoft.EntityFrameworkCore.Storage;

, чтобы получить доступ к GetDbTransaction способ расширения:

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