码迷,mamicode.com
首页 > Web开发 > 详细

ASP.NET Core 2.2 系列【六】泛型仓储模式

时间:2019-11-23 20:14:44      阅读:88      评论:0      收藏:0      [点我收藏+]

标签:减少代码冗余   over   sse   slist   记录   get   bapi   service   一个   

为什么要使用泛型仓储?好处是?

前两章在autofac注入的时候,用的User类作为例子,写了增删改查四个接口,也就是仓储的GRUD。

        当我们再添加一个实体(比如Student)时,StudentRepository跟UserRepository代码几乎一样的代码,重复量很大,为了减少冗余、提高工作效率,使用泛型仓储最好不过了

好处:

减少代码冗余

提高了开发人员的工作效率

提高对数据库访问的维护

一、泛型仓储接口和泛型仓储实现类

泛型仓储接口

在类库项目上右键->添加->新建文件夹,命名为Repository,存放泛型仓储接口及实现类。在Repository文件夹下面新建 泛型仓储接口类:IRepository,如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using NetCoreWebApi.Repository.Dto;

namespace NetCoreWebApi.Repository.Repository
{
    public interface IRepository<T> where T : class
    {
        /// <summary>
        /// 添加实体(单个)
        /// </summary>
        /// <param name="entity">实体对象</param>
        int Add(T entity);

        /// <summary>
        /// 批量插入实体(多个)
        /// </summary>
        /// <param name="list">实体列表</param>
        int AddRange(List<T> list);

        /// <summary>
        /// 删除实体(单个)
        /// </summary>
        /// <param name="entity"></param>
        int Remove(T entity);

        /// <summary>
        /// 批量删除实体(多个)
        /// </summary>
        /// <param name="list">实体列表</param>
        int RemoveRange(List<T> list);
        /// <summary>
        /// 获取所有 
        /// </summary>
        /// <returns></returns>
        IQueryable<T> GetAll();
        /// <summary>
        /// 分页条件查询
        /// </summary>
        /// <typeparam name="TKey">排序类型</typeparam>
        /// <param name="pageIndex">当前页</param>
        /// <param name="pageSize">每页大小</param>
        /// <param name="predicate">条件表达式</param>
        /// <param name="isAsc">是否升序排列</param>
        /// <param name="keySelector">排序表达式</param>
        /// <returns></returns>
        Page<T> SearchFor<TKey>(int pageIndex, int pageSize, Expression<Func<T, bool>> predicate,
            bool isAsc, Expression<Func<T, TKey>> keySelector);
        /// <summary>
        /// 获取实体(主键)
        /// </summary>
        /// <param name="id">主键id</param>
        /// <returns></returns>
        T GetModelById(object id);
        /// <summary>
        /// 获取实体(条件)
        /// </summary>
        /// <param name="predicate">条件表达式</param>
        /// <returns></returns>
        T GetModel(Expression<Func<T, bool>> predicate);
        /// <summary>
        /// 查询记录数
        /// </summary>
        /// <param name="predicate">条件表达式</param>
        /// <returns>记录数</returns>
        int Count(Expression<Func<T, bool>> predicate);
        /// <summary>
        /// 是否存在
        /// </summary>
        /// <param name="anyLambda">查询表达式</param>
        /// <returns>布尔值</returns>
        bool Exist(Expression<Func<T, bool>> anyLambda);
    }
}

泛型仓储实现类

在Repository文件夹下面新建 泛型仓储实现类:Repository,并继承IRepository,如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using NetCoreWebApi.Model;
using NetCoreWebApi.Repository.Dto;

namespace NetCoreWebApi.Repository.Repository
{
    public class Repository<T> : IRepository<T> where T : class
    {
        private readonly MyDbContext _dbContext;
        private DbSet<T> _entity;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbContext"></param>
        public Repository(MyDbContext dbContext)
        {
            _dbContext = dbContext;
        }
        private DbSet<T> Entity => _entity ?? (_entity = _dbContext.Set<T>());
        /// <summary>
        /// 添加实体(单个)
        /// </summary>
        /// <param name="entity">实体对象</param>
        public int Add(T entity)
        {
            Entity.Add(entity);
            return _dbContext.SaveChanges();
        }
        /// <summary>
        /// 批量插入实体(多个)
        /// </summary>
        /// <param name="list">实体列表</param>
        public int AddRange(List<T> list)
        {
            Entity.AddRange(list);
            return _dbContext.SaveChanges();
        }

        /// <summary>
        /// 删除实体(单个)
        /// </summary>
        /// <param name="entity"></param>
        public int Remove(T entity)
        {
            Entity.Remove(entity);
            return _dbContext.SaveChanges();
        }
        /// <summary>
        /// 批量删除实体(多个)
        /// </summary>
        /// <param name="list">实体列表</param>
        public int RemoveRange(List<T> list)
        {
            Entity.RemoveRange(list);
            return _dbContext.SaveChanges();
        }
        /// <summary>
        /// 获取所有
        /// </summary>
        /// <returns></returns>
        public IQueryable<T> GetAll()
        {
            return Entity.AsQueryable().AsNoTracking();
        }
        /// <summary>
        /// 条件查询
        /// </summary>
        /// <typeparam name="TKey">排序类型</typeparam>
        /// <param name="pageIndex">当前页</param>
        /// <param name="pageSize">每页大小</param>
        /// <param name="isAsc">是否升序排列</param>
        /// <param name="predicate">条件表达式</param>
        /// <param name="keySelector">排序表达式</param>
        /// <returns></returns>
        public Page<T> SearchFor<TKey>(int pageIndex, int pageSize, Expression<Func<T, bool>> predicate, bool isAsc,
            Expression<Func<T, TKey>> keySelector)
        {
            if (pageIndex <= 0 || pageSize <= 0) throw new Exception("pageIndex或pageSize不能小于等于0");
            var page = new Page<T> { PageIndex = pageIndex, PageSize = pageSize };
            var skip = (pageIndex - 1) * pageSize;
            var able = Entity.AsQueryable().AsNoTracking();
            if (predicate == null)
            {
                var count = Entity.Count();
                var query = isAsc
                    ? able.OrderBy(keySelector).Skip(skip).Take(pageSize)
                    : able.OrderByDescending(keySelector).Skip(skip).Take(pageSize);
                page.TotalRows = count;
                page.LsList = query.ToList();
                page.TotalPages = page.TotalRows / pageSize;
                if (page.TotalRows % pageSize != 0) page.TotalPages++;
            }
            else
            {
                var queryable = able.Where(predicate);
                var count = queryable.Count();
                var query = isAsc
                    ? queryable.OrderBy(keySelector).Skip(skip).Take(pageSize)
                    : queryable.OrderByDescending(keySelector).Skip(skip).Take(pageSize);
                page.TotalRows = count;
                page.LsList = query.ToList();
                page.TotalPages = page.TotalRows / pageSize;
                if (page.TotalRows % pageSize != 0) page.TotalPages++;
            }
            return page;
        }
        /// <summary>
        /// 获取实体
        /// </summary>
        /// <param name="id">主键id</param>
        /// <returns></returns>
        public T GetModelById(object id)
        {
            return Entity.Find(id);
        }

        /// <summary>
        /// 获取实体(条件)
        /// </summary>
        /// <param name="predicate">条件表达式</param>
        /// <returns></returns>
        public T GetModel(Expression<Func<T, bool>> predicate)
        {
            return Entity.FirstOrDefault(predicate);
        }
        /// <summary>
        /// 查询记录数
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public int Count(Expression<Func<T, bool>> predicate)
        {
            return predicate != null ? Entity.Where(predicate).Count() : Entity.Count();
        }
        /// <summary>
        /// 是否存在
        /// </summary>
        /// <param name="anyLambda"></param>
        /// <returns></returns>
        public bool Exist(Expression<Func<T, bool>> anyLambda)
        {
            return Entity.Any(anyLambda);
        }
    }
}

分页Page类

using System.Collections.Generic;

namespace NetCoreWebApi.Repository.Dto
{
    public class Page<T>
    {
        /// <summary>
        /// 当前页
        /// </summary>
        public int PageIndex { get; set; }
        /// <summary>
        /// 总页数
        /// </summary>
        public int TotalPages { get; set; }
        /// <summary>
        /// 集合总数
        /// </summary>
        public int TotalRows { get; set; }
        /// <summary>
        /// 每页项数
        /// </summary>
        public int PageSize { get; set; }
        /// <summary>
        /// 集合
        /// </summary>
        public IList<T> LsList { get; set; }
    }
}

二、仓储的泛型的依赖注入。

修改Startup.cs启动类中ConfigureServices方法

        public static IContainer ApplicationContainer { get; set; }
        /// <summary>
        /// //负责注入服务
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            //获取数据库连接字符串
            var connectionStr = Configuration.GetConnectionString("SqlServer");
            services.AddDbContext<MyDbContext>
                (options => options.UseSqlServer(connectionStr,
                    e => e.MigrationsAssembly("NetCoreWebApi.Model")));
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            //初始化容器
            var builder = new ContainerBuilder();
            //管道寄居
            builder.Populate(services);
            //注册业务
            builder.RegisterAssemblyTypes(Assembly.Load("NetCoreWebApi.Repository"), Assembly.Load("NetCoreWebApi.Repository"))
                .Where(t => t.Name.EndsWith("Repository"))
                .AsImplementedInterfaces();
            //注册仓储,所有IRepository接口到Repository的映射
            builder.RegisterGeneric(typeof(Repository<>))
                //InstancePerDependency:默认模式,每次调用,都会重新实例化对象;每次请求都创建一个新的对象;
                .As(typeof(IRepository<>)).InstancePerDependency();
            //构造
            ApplicationContainer = builder.Build();
            //将AutoFac反馈到管道中
            return new AutofacServiceProvider(ApplicationContainer);
        }

 

 三、测试

修改业务层---UserRepository

给泛型类指定ThUser,红色字体是主要更改部分。

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 IRepository<TbUser> _userRepository;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="userRepository"></param>
        public UserRepository(IRepository<TbUser> userRepository)
        {
            _userRepository = userRepository;
        }
        /// <summary>
        /// 添加用户
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Add(TbUser entity)
        {
            return _userRepository.Add(entity);
        }
        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Remove(TbUser entity)
        {
            return _userRepository.Remove(entity);
        }
        /// <summary>
        /// 查询用户
        /// </summary>
        /// <returns></returns>
        public IList<TbUser> GetAll()
        {
            return _userRepository.GetAll().ToList();
        }
    }
}

运行项目执行接口,可以看到跟之前一样 

技术图片

如果有其他实体只需要改变传入的T就可以了,不需要再重新创建TEntityRepository

ASP.NET Core 2.2 系列【六】泛型仓储模式

标签:减少代码冗余   over   sse   slist   记录   get   bapi   service   一个   

原文地址:https://www.cnblogs.com/tenghao510/p/11918885.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!