多种仓储模式


多种仓储模式

IBaseRepository + BaseRepository 模式(适用于小项目,扩展性差)

  • IRepository接口包含了基本的CRUD操作,如果业务中还需要扩展其他操作,只需在IRepository接口中添加。
  • Repository实现了IRepository接口。其中ISqlHelp接口包含获取数据库链接字符串的功能,_context为EF或EF Core类库。
  • 优点是简单、快速,缺点是扩展性差且违反开放-关闭原则(Open-Close Principle)

IBaseRepository.cs

public interface IBaseRepository<T> where T : class, new()
{     
    T Create(T model);
    T Update(T model);
    T Query(Guid guid);
    T Query(Espression<Func<T, bool>> expression);
    int Delete(Guid guid);
    int BatchDelete(IList<Guid> guids);
    List<T> GetAll();
    List<T> GetAll(Expression<Func<T, bool>> expression, Expression<Func<T, dynamic>> sortPredicate, SortOrder sortOrder, int skip, int take, out int total);
}

BaseRepository.cs

public class BaseRepository<T> : IBaseRepository<T> where T : class, new() 
{
    //数据上下文
    internal DbContext _context;

    public BaseRepository(DbContext context) 
    {
        _context = context
    }

    public T Create(T model) 
    {
        _context.Entry(model).State = EntityState.Added;
        var createRowCount = _context.SaveChanges();
        return createRowCount > 0 ? model : null;
    }

    public T Update(T model)
    {
        _context.Entry(model).State = EntityState.Modified;
        var updateRowAcount = _context.SaveChanges();
        return updateRowAcount > 0 ? model : null;
    }

    public T Query(Guid guid)
    {
        return _context.Set<T>().Find(guid);
    }

    public T Query(Expression<Func<T, bool>> expression)
    {
        return _context.Set<T>().FirstOrDefault(expression);
    }

    public int Delete(Guid guid)
    {
        var model = _context.Set<T>().Find(guid);
        if (model == null) 
        {
            throw new ArgumentOutOfRangeException(nameof(guid));
        }
        _context.Entry(model).State = EntityState.Deleted;
        return _context.SaveChanges();
    }

    public int BatchDelete(IList<Guid> guids)
    {
        foreach (var item in guids)
        {
            var model = _context.Set<T>().Find(item);
            _context.Entry(model).State = EntityState.Deleted;
        }
        return _context.SaveChanges();
    }

    public List<T> GetAll()
    {
        return _context.Set<T>().Where(q => true).ToList();
    }

    public List<T> GetAll(Expression<Func<T, bool>> expression, Expression<Func<T, dynamic>> sortPredicate, SortOrder sortOrder, int skip, int take, out int total)
    {
        total = _context.Set<T>().Where(expression).Count();
        switch (sortOrder)
        {
            case SortOrder.Ascending:
                return _context.Set<T>().Where(expression).OrderBy(sortPredicate).Skip(skip).Take(take).ToList();
                    
            case SortOrder.Descending:
                return _context.Set<T>().Where(expression).OrderByDescending(sortPredicate).Skip(skip).Take(take).ToList();
        }
        throw new InvalidOperationException("分页查询必须指定排序字段和排序顺序。");
    }
}

AdminServer.cs

public sealed class AdminServer
{
    private readonly IBaseRepository<User> _adminRepository;

    public AdminServer(IBaseRepository<User> adminRepository)
    {
        _adminRepository = adminRepository;
    }

    public void CreateUser()
    {
        var admin = new User();
        _adminRepository.Create(admin);
    }
}

IBaseRepository+BaseRepository+IRepository+Repository(可扩展性好,未处理并发)

将BaseRepository.cs的实现方法上加上virtual关键字,使方法可以重载,每添加一个实体,需要添加对应的接口和实现

BaseRepository.cs

public class BaseRepository<T> : IBaseRepository<T> where T : class, new() 
{
    //数据上下文    
    internal DbContext _context;
    
    public BaseRepository(DbContext context) 
    {
        _context = context
    }
    

    public virtual T Create(T model) 
    {
        //略
    }

    public virtual T Update(T model)
    {
        //略
    }

    public virtual T Query(Guid guid)
    {
        //略
    }

    public virtual T Query(Expression<Func<T, bool>> expression)
    {
        //略
    }

    public virtual int Delete(Guid guid)
    {
        //略
    }

    public virtual int BatchDelete(IList<Guid> guids)
    {
        //略
    }

    public virtual List<T> GetAll()
    {
        //略
    }

    public virtual List<T> GetAll(Expression<Func<T, bool>> expression, Expression<Func<T, dynamic>> sortPredicate, SortOrder sortOrder, int skip, int take, out int total)
    {
        //略
    }
}

IRepository.cs

public partial interface IAdminRepository : IBaseRepository<Admin>
{
    bool IsExist(Admin admin);
}
public partial interface IUserRepository : IBaseRepository<User>
{

}

Repository.cs

public partial class AdminRepository : BaseRepository<Admin>,IAdminRepository
{
    public AdminRepository(ISqlHelp sqlHelp) : base(sqlHelp)
    {

    }
    public bool IsExist(Admin admin)
    {
        //略
    }
}
public partial class UserRepository : BaseRepository<User>,IUserRepository
{
    public UserRepository(ISqlHelp sqlHelp) : base(sqlHelp)
    {

    }
}

AdminServer.cs

public sealed class AdminServer
{
    private readonly IAdminRepository _adminRepository;

    public AdminServer(IAdminRepository adminRepository)
    {
        _adminRepository = adminRepository;
    }

    public void CreateUser()
    {
        var admin = new User();
        _adminRepository.Create(admin);
    }

    public bool IsExist(Admin admin)
    {
        return _adminRepository.IsExist(admin);
    }
}

仓储模式+工作单元模式(扩展性高,有并发处理需求)

使用工作单元的原因是可以提高数据库写操作负载,并且在仓储模式中可以根据不同的数据库链接字符串读不同的库。

IUnitOfWork.cs

public interface IUnitOfWork : IDisposable
    {
        _context _context { get; set; }

        /// <summary>
        /// 提交所有更改
        /// </summary>
        Task CommitAsync();
        
        #region Methods
        /// <summary>
        /// 将指定的聚合根标注为“新建”状态。
        /// </summary>
        /// <typeparam name="T">需要标注状态的聚合根类型。</typeparam>
        /// <param name="obj">需要标注状态的聚合根。</param>
        void RegisterNew<T>(T obj) where T : class, IEntity;

        /// <summary>
        /// 将指定的聚合根标注为“更改”状态。
        /// </summary>
        /// <typeparam name="T">需要标注状态的聚合根类型。</typeparam>
        /// <param name="obj">需要标注状态的聚合根。</param>
        void RegisterModified<T>(T obj) where T : class;

        /// <summary>
        /// 将指定的聚合根标注为“删除”状态。
        /// </summary>
        /// <typeparam name="T">需要标注状态的聚合根类型。</typeparam>
        /// <param name="obj">需要标注状态的聚合根。</param>
        void RegisterDeleted<T>(T obj) where T : class;
        #endregion
    }

UnitOfWork.cs

public class UnitOfWork : IUnitOfWork
{
    public _context _context { get; set; }
    public UnitOfWork(IContextHelper contextHelp)
    {
        _context = contextHelp._context;
    }
    private AdminRepository _adminRepository;

    public AdminRepository AdminRepository
    {
        get
        {
            return _adminRepository ?? new AdminRepository(_context);
        }
    }

    public virtual async Task CommitAsync()
    {
        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            ex.Entries.Single().Reload();
        }
    }
    
    public virtual void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    
    private void Dispose(bool disposing)
    {
        if (!disposing) 
        {
            return;
        }
        if (_context == null) 
        {
            return;
        }
        _context.Dispose();
        _context = null;
    }

    public virtual void RegisterNew<TEntity>(TEntity obj) where TEntity : class, IEntity
    {
        _context.Set<TEntity>().Add(obj);
    }

    public virtual void RegisterModified<TEntity>(TEntity obj) where TEntity : class
    {
        _context.Entry(obj).State = EntityState.Modified;
    }

    public virtual void RegisterDeleted<TEntity>(TEntity obj) where TEntity : class
    {
        _context.Entry(obj).State = EntityState.Deleted;
    }

}

AdminServer.cs

public class AdminServer
{
    private UnitOfWork unit;

    public AdminServer(UnitOfWork unitOfWork)
    {
        unit = unitOfWork;
    }

    public IEnumerable Get()
    {
        return unit.AdminRepository.GetAll();
    }
}

文章作者: caty
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 caty !
 上一篇
微服务-Consul学习 微服务-Consul学习
Consul介绍 Consul 是由 HashiCorp 公司推出的开源软件,用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,Consul 的方案更“一站式”,内置了服务注册与发现框 架、分布一致性协议实现、健康检查、
2019-03-05
下一篇 
聚会随想 聚会随想
前言过完年没多久,我便和关系比较好进行了2019年春节后的第一次聚会,地点还是在广州,时间定在了元宵节那周的周六(02.24).这次聚会既有好奇某个脱单的小伙伴是怎么脱单的,也有因为有小伙伴要跳槽,还有是有小伙伴计划买电脑的,想去实体店看看
2019-02-24
  目录