我正在开发一个.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的实现,但是在.NET Core中,我没有DbContextTransaction
。
我还没有使用工作单元。目前我的服务如下所示:
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
。
解决方案是什么?
好吧,我不是实体框架方面的专家,但我是根据存储库和工作单元来回答的。
首先,避免不必要的其他通用存储库包装器,因为您已经在使用full-ORM。请参考此答案。
但在.NET Core中,我没有DbContextTransaction。
在这种情况下,DbContextTransaction
很重要,但不是实施工作单元的关键。重要的是DBContext
.跟踪和刷新更改的是DBContext
。您拨打DBContext
SaveChanges
以通知您已完成。
我想让这个交易
我相信一定有一些东西可以取代DbContextTransaction
或代表交易。
Microsoft建议的一种方法是按如下方式使用它:
context.Database.BeginTransaction()
context
在哪里DbContext
.
这里解释了其他方法。
另外,避免对所有涉及的存储库使用SaveChangesAsync。
这是可能的。不要将SaveChanges
放在存储库中。把它放在单独的类中。在每个具体/通用存储库中注入该类。最后,完成后只需拨打SaveChanges
一次即可。有关示例代码,您可以查看此问题。但是,该问题中的代码有一个错误,该错误已在我提供给它的答案中修复。