如何使用通用存储库模式实现事务?

How to implement Transactions with Generic Repository Pattern?

我正在开发一个 .NET Core 应用程序,我在其中利用通用存储库模式,我想知道如何实现事务:

IGenericRepository

public interface IGenericRepository<T>
    {
        Task InsertAsync(T insert);
        Task<bool> RemoveAsync(object id);
        Task UpdateAsync(T entity);
        Task<T> GetByIdAsync(object id,string includeProperties="");
        Task<IQueryable<T>> GetAsync(Expression<Func<T, bool>> filter=null,
                                     int? skip=null,
                                     int? take=null,
                                     Func<IQueryable<T>,IOrderedQueryable<T>> orderBy = null,
                                     string includeProperties = "");
        Task SaveAsync();
    }

我正在查看也使用 UnitOfWork 的 this 实现,但在 .NET Core 中,我没有 DbContextTransaction

我还没有使用 UnitOfWork。目前我的服务是这样的:

public class SomeService
{
   IGenericRepository<A> arepo;
   IGenericRepository<B> brepo;
   public SomeService(IGenericRepository<A> arepo,IGenericRepository<B> brepo)
   {
        this.arepo=arepo;
        this.brepo=brepo;
   }
   public async Task DoTransaction(id)
   {
        var a=await arepo.GeyById(id)
        await brepo.RemoveAsync(a.Id);
        await brepo.SaveChangesAsync();
        await arepo.InsertAsync([something]);
        await arepo.SaveChanges();
   }  
}

我想使这个事务成为事务性的,并且避免对所有涉及的存储库使用 SaveChangesAsync

什么是解决方案?

好吧,我不是 entity framework 方面的专家,但我会根据存储库和工作单元来回答。

首先,避免对额外的通用存储库进行不必要的包装,因为您已经在使用完整的 ORM。请参考回答。

but in .NET Core i do not have a DbContextTransaction.

DbContextTransaction 很重要,但不是在这种情况下实现工作单元的关键。重要的是DBContextDBContext 跟踪并刷新更改。您在 DBContext 上调用 SaveChanges 通知您已完成。

I would want to make this transactional

我确定一定有可用的东西来替代 DbContextTransaction 或代表交易。

Microsoft 建议的一种方法是如下使用它:

context.Database.BeginTransaction()

其中 contextDbContext

其他方式说明here.

also ,avoid using SaveChangesAsync for all repos that get involved

这是可能的。不要将 SaveChanges 放入存储库中。单独放在class。在每个 concrete/generic 存储库中注入 class。最后,完成后只需调用 SaveChanges 一次。对于示例代码,您可以查看 问题。但是,该问题中的代码有一个错误,该错误已在我提供给它的答案中修复。