ASP.NET Core 2.2 WebApi 系列【七】泛型仓储模式和工作单元

在之前的泛型仓储模式实现中,每个增删改都调用了SaveChanges方法,导致每次更新都提交了事务。

在实际开发过程中,我们经常遇到同时操作多张表数据,那么按照之前的写法,对数据库提交了多次操作,开启了多事务,不能保证数据的一致性,结合工作单元(UnitOfWork)是为了把多次操作放到同一事务中,要么都成功(Commit),要么都失败(Rollback),保证了数据的一致性。

 修改仓储类

先把仓储接口中增删改接口无返回(void)值类型,然后去仓储实现类去掉SaveChanges方法,交给UOW统一处理

实现UOW

把SaveChanges抽离出来,定义IUnitOfWork接口

namespace NetCoreWebApi.Repository
{
    /// <summary>
    /// 接口
    /// </summary>
    public interface IUnitOfWork
    {
        /// <summary>
        /// 保存
        /// </summary>
        /// <returns></returns>
        int SaveChanges();
    }
}

实现IUnitOfWork接口

using System;
using Microsoft.EntityFrameworkCore;

namespace NetCoreWebApi.Repository
{
    /// <summary>
    /// 实现类
    /// </summary>
    public class UnitOfWork<TDbContext> : IUnitOfWork where TDbContext : DbContext
    {
        /// <summary>
        /// dbContext上下文
        /// </summary>
        private readonly TDbContext _dbContext;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbContext"></param>
        public UnitOfWork(TDbContext dbContext)
        {
            _dbContext = dbContext;
        }

        /// <summary>
        /// 保存
        /// </summary>
        public int SaveChanges()
        {
            int code;
            try
            {
                code = _dbContext.SaveChanges();
            }
            catch (DbUpdateException e)
            {
                throw new Exception(e.InnerException == null ? e.Message : e.InnerException.Message);
            }
            return code;
        }
    }
}

UOW依赖注入

因为AddDbContext默认生命周期是Scoped,所以用AddScoped注册UOW,确保每次请求共用同一个DbContex对象。

            //注入DbContext
            services.AddDbContext<MyDbContext> (options => options.UseSqlServer(connectionStr,e => e.MigrationsAssembly("NetCoreWebApi.Model")));
            //注入Uow依赖
            services.AddScoped<IUnitOfWork, UnitOfWork<MyDbContext>>();

使用UOW

修改UserRepository业务层

using NetCoreWebApi.Model.Models;
using NetCoreWebApi.Repository.Interface;
using NetCoreWebApi.Repository.Repository;
using System.Collections.Generic;
using System.Linq;

namespace NetCoreWebApi.Repository.Implement
{
    /// <summary>
    /// 业务处理
    /// </summary>
    public class UserRepository : IUserRepository
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IRepository<TbUser> _userRepository;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="userRepository"></param>
        /// <param name="unitOfWork"></param>
        public UserRepository(IRepository<TbUser> userRepository, IUnitOfWork unitOfWork)
        {
            _userRepository = userRepository;
            _unitOfWork = unitOfWork;
        }
        /// <summary>
        /// 添加用户
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public void Add(TbUser entity)
        {
            _userRepository.Add(entity);
            _unitOfWork.SaveChanges();
        }
        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public void Remove(TbUser entity)
        {
            _userRepository.Remove(entity);
            _unitOfWork.SaveChanges();
        }
        /// <summary>
        /// 查询用户
        /// </summary>
        /// <returns></returns>
        public IList<TbUser> GetAll()
        {
            return _userRepository.GetAll().ToList();
        }
    }
}

遇到多仓储持久化操作时,用构造函数依赖注入相应的仓储即可。

猜你喜欢

转载自www.cnblogs.com/tenghao510/p/11921501.html