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 System.Collections.Generic;
using System.Linq;
using NetCoreWebApi.Model.Models;
using NetCoreWebApi.Repository.Interface;
using NetCoreWebApi.Repository.Repository;

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 int Add(TbUser entity)
        {
            _userRepository.Add(entity);
            return _unitOfWork.SaveChanges();
        }
        /// <summary>
        /// 刪除用戶
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Remove(TbUser entity)
        {
            _userRepository.Remove(entity);
            return _unitOfWork.SaveChanges();
        }
        /// <summary>
        /// 查詢用戶
        /// </summary>
        /// <returns></returns>
        public IList<TbUser> GetAll()
        {
            return _userRepository.GetAll().ToList();
        }
    }
}

遇到多倉儲持久化操作時,用構造函數依賴注入相應的倉儲即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM