EntityFrameworkCore 交换 DbConnection添加事务

问题描述

我将大型数据库模型(数百个表)拆分为多个 EntityFrameworkCore DbContext。当我在两个(或多个)不同的 DbContext 中修改多个实体时,这是一个非常常见的用例,但我需要在单个事务中提交此操作。

我使用 IReporitory 模式,将 ISomeRepository 实现的实例注入到 Controller 中,如下所示:

[HttpPost]
public asycn Task DoSomeWorkAsync()
{
   using (var transaction = this.IEmployeesRepository.BeginTransaction())
   {
       // do some work
       await this.IEmployeesRepository.SaveChangesAsync();

       // do another work
       await this.IPayrollRepository.SaveChangesAsync();
   }
}

EmployeeDbContext 实现了 IEmployeeRepository 接口,PayrollDbContexts 实现了 IPayrollRepository。

我以错误告终: system.invalidOperationException: The specified transaction is not associated with the current connection. Only transactions associated with the current connection may be used.

存在很handy documentation,基本解决了问题。

很酷,但我无法创建 EmployeeDbContext 的新实例,如文档中所述,因为我只使用抽象 - 接口。我正在寻找一些如何更改/交换/注入/替换现有 DbContext 中的 DbConnection 的方法

我正在考虑实施 Clone 方法,例如

[HttpPost]
public asycn Task DoSomeWorkAsync()
{
   using (var transaction = this.IEmployeesRepository.BeginTransaction())
   {
       await this.IEmployeesRepository.SaveChangesAsync();

       var payrollRepoClone = IPayrollRepository.Clone(transaction);

       await payrollRepoClone.SaveChangesAsync();
   }
}

然后我会做

public class PayrollDbContext : DbContext,IPayrollRepository
{

   private readonly DbConnection dbConnection;

   public PayrollDbContext Clone(DbTransaction tran)
   {
      return new PayrollDbContext(tran.GetDbTransaction.Connection);
   }

   protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
   {
        optionsBuilder.UsesqlServer(dbConnection);
   }
}

但我试图避免这种与 sql Server 的紧密耦合,因为目前在我解析 IPayrolRepository 实例的服务容器中的 IoC 中调用UseNpgsql。和 UseInMemoryDatabase 在单元测试中。这会使我的测试崩溃(或者至少需要在 OnConfiguring 中使用一些脏的 if/else)

您对如何将事务或 dbConnection 注入现有 DbContext 有任何提示吗?

谢谢

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)