连接已经在事务中-CreateTables EF Core上的错误

时间:2019-06-17 08:51:27

标签: c# sql-server asp.net-core entity-framework-core

我想使用上下文在现有表中插入一条记录,并使用不同的上下文在同一事务中创建新表。这两个上下文共享相同的连接,但是当我想执行CreateTables函数时,出现以下错误:

  

该连接已经在一个事务中,不能参与另一个事务。

这是什么原因,某个地方是否隐藏了多个事务?如何在同一笔交易中执行这两项更改?

交易:

using (var newTablesContext = new NewTablesContext(options, schema))
{
  using (var transaction = existingContext.Database.BeginTransaction())
  {
    try
    {
      newTablesContext.Database.UseTransaction(transaction.GetDbTransaction());
      RelationalDatabaseCreator databaseCreator =
        (RelationalDatabaseCreator)newTablesContext.Database.GetService<IDatabaseCreator>();
      databaseCreator.CreateTables();

      existingContext.Entities.Add(entity);
      if (existingContext.SaveChanges() < 1)
      {
        throw new Exception();
      }

      transaction.Commit();
    }
    catch (Exception e)
    {
      transaction.Rollback();
      return null;
    }
  }
}

Startup.cs

private Action<IServiceProvider, DbContextOptionsBuilder> SqlServerConfigurator(IServiceCollection services)
{
  var connectionString = Configuration.GetConnectionString("dbConnection");
  services.AddScoped(s => new SqlConnection(connectionString));

  return (locator, builder) =>
  {
    var connection = locator.GetRequiredService<SqlConnection>();

    builder.UseSqlServer(connection)
      .ReplaceService<IModelCacheKeyFactory, DbSchemaAwareModelCacheKeyFactory>();
  };
}

ConfigureServices内部:

var configSqlServer = SqlServerConfigurator(services);

services.AddDbContext<ExistingContext>(configSqlServer);

1 个答案:

答案 0 :(得分:0)

您不需要使用此行

newTablesContext.Database.UseTransaction(transaction.GetDbTransaction());

以下是我使用异步事务处理的代码。您可以查看作为参考。如果您需要任何帮助,请告诉我。

using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
    try
    {
        var commentToUpdate = await _unitOfWork.Repository<Comment>().Query().Where(cm => cm.Id == commentId).SingleOrDefaultAsync();
        commentToUpdate.CommentStatus = commentStatus;
        await _unitOfWork.Repository<Comment>().UpdateAsync(commentToUpdate);
        transaction.Complete();
        return true;
    }
    catch (Exception)
    {
        _unitOfWork.Rollback();
        return false;
    }
}