如何使用通用存储库模式实现事务?
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
很重要,但不是在这种情况下实现工作单元的关键。重要的是DBContext
。 DBContext
跟踪并刷新更改。您在 DBContext
上调用 SaveChanges
通知您已完成。
I would want to make this transactional
我确定一定有可用的东西来替代 DbContextTransaction
或代表交易。
Microsoft 建议的一种方法是如下使用它:
context.Database.BeginTransaction()
其中 context
是 DbContext
。
其他方式说明here.
also ,avoid using SaveChangesAsync for all repos that get involved
这是可能的。不要将 SaveChanges
放入存储库中。单独放在class。在每个 concrete/generic 存储库中注入 class。最后,完成后只需调用 SaveChanges
一次。对于示例代码,您可以查看 问题。但是,该问题中的代码有一个错误,该错误已在我提供给它的答案中修复。
我正在开发一个 .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
很重要,但不是在这种情况下实现工作单元的关键。重要的是DBContext
。 DBContext
跟踪并刷新更改。您在 DBContext
上调用 SaveChanges
通知您已完成。
I would want to make this transactional
我确定一定有可用的东西来替代 DbContextTransaction
或代表交易。
Microsoft 建议的一种方法是如下使用它:
context.Database.BeginTransaction()
其中 context
是 DbContext
。
其他方式说明here.
also ,avoid using SaveChangesAsync for all repos that get involved
这是可能的。不要将 SaveChanges
放入存储库中。单独放在class。在每个 concrete/generic 存储库中注入 class。最后,完成后只需调用 SaveChanges
一次。对于示例代码,您可以查看