ASP.NET Core 2.2 系列【七】泛型倉儲模式和工做單元

在以前的泛型倉儲模式實現中,每一個增刪改都調用了SaveChanges方法,致使每次更新都提交了事務。數據庫

在實際開發過程當中,咱們常常遇到同時操做多張表數據,那麼按照以前的寫法,對數據庫提交了屢次操做,開啓了多事務,不能保證數據的一致性,結合工做單元(UnitOfWork)是爲了把屢次操做放到同一事務中,要麼都成功(Commit),要麼都失敗(Rollback),保證了數據的一致性。函數

 修改倉儲類

先把倉儲接口中增刪改接口無返回(void)值類型,而後去倉儲實現類去掉SaveChanges方法,交給UOW統一處理spa

實現UOW

把SaveChanges抽離出來,定義IUnitOfWork接口code

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對象。blog

            //注入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();
        }
    }
}

遇到多倉儲持久化操做時,用構造函數依賴注入相應的倉儲便可。生命週期

相關文章
相關標籤/搜索