数据访问仓储模式的事务管理(Unit of Work)

原创https://blog.csdn.net/huanghuangtongxue/article/details/79215136

1、定义IUnitOfWork接口

public interface IUnitOfWork
    {
        /// <summary>
        /// 提交更改
        /// </summary>
        /// <returns></returns>
        int SaveChanges();
        /// <summary>
        /// 提交更改异步
        /// </summary>
        /// <returns></returns>
        Task<int> SaveChangesAsync();
        /// <summary>
        /// 开启事务
        /// </summary>
        void BeginTransaction();
        /// <summary>
        /// 提交事务
        /// </summary>
        void CommitTransaction();
        /// <summary>
        /// 回滚事务
        /// </summary>
        void RollBackTransaction();
    }

2、定义 IUnitOfWork的实现类UnitOfWork,定义泛型TDBContext其类型必须是DbContext,通过构造函数依赖注入_dbContext

public class UnitOfWork<TDBContext> : IUnitOfWork where TDBContext : DbContext
    {
        private readonly TDBContext _dbContext;
 
        public UnitOfWork(TDBContext dbContext)
        {
            _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
        }
        public int SaveChanges()
        {
            return _dbContext.SaveChanges();
        }
 
        public async Task<int> SaveChangesAsync()
        {
            return await _dbContext.SaveChangesAsync();
        }
        public void BeginTransaction()
        {
            _dbContext.Database.BeginTransaction();
        }
 
        public void CommitTransaction()
        {
            _dbContext.Database.CommitTransaction();
        }
 
        public void RollBackTransaction()
        {
            _dbContext.Database.RollbackTransaction();
        }
    }

3、修改仓储的实现类,把 _dbContext.SaveChanges();这行代码全部删除。这样就不会每次更改就会提交,而是交由IUnitOfWork 统一的提交事务。

4、注册IUnitOfWork的时候要注意,要确保 UnitOfWork和DBContext 在整个请求中共用同一个对象,这样才能通过IUnitOfWork 来一次性提交事务。AddDbContext这个方法它默认的生命周期为ServiceLifetime.Scoped,所以只需要注册IUnitOfWork的时候使用AddScoped方法,将其生命周期限定为Scoped,就能保证每次请求都是共用同一个对象。

services.AddDbContext<YunSourseContext>(option => option.UseSqlServer(Configuration.GetConnectionString("Default"), b => b.UseRowNumberForPaging()));//配置sqlserver
services.AddScoped<IUnitOfWork,UnitOfWork<YunSourseContext>>();//注入UOW依赖,确保每次请求都是同一个对象,生命周期Scope

5、调用_unitOfWork.SaveChanges();等等

posted on 2020-11-25 11:33  菜鸟客栈  阅读(370)  评论(0编辑  收藏  举报

导航