欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-11-08 16:54:40
在之前的泛型仓储模式实现中,每个增删改都调用了SaveChanges方法,导致每次更新都提交了事务。 在实际开发过程中,我们经常遇到同时操作多张表数据,那么按照之前的写法,对数据库提交了多次操作,开启了多事务,不能保证数据的一致性,结合工作单元(UnitOfWork)是为了把多次操作放到同一事务中, ......

在之前的泛型仓储模式实现中,每个增删改都调用了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();
        }
    }
}

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