在以前的泛型倉儲模式實現中,每一個增刪改都調用了SaveChanges方法,致使每次更新都提交了事務。數據庫
在實際開發過程當中,咱們常常遇到同時操做多張表數據,那麼按照以前的寫法,對數據庫提交了屢次操做,開啓了多事務,不能保證數據的一致性,結合工做單元(UnitOfWork)是爲了把屢次操做放到同一事務中,要麼都成功(Commit),要麼都失敗(Rollback),保證了數據的一致性。函數
先把倉儲接口中增刪改接口無返回(void)值類型,而後去倉儲實現類去掉SaveChanges方法,交給UOW統一處理spa
把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; } } }
由於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>>();
修改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(); } } }
遇到多倉儲持久化操做時,用構造函數依賴注入相應的倉儲便可。生命週期