欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-13 07:55:25
为什么要使用泛型仓储?好处是? 前两章在autofac注入的时候,用的User类作为例子,写了增删改查四个接口,也就是仓储的GRUD。 当我们再添加一个实体(比如Student)时,StudentRepository跟UserRepository代码几乎一样的代码,重复量很大,为了减少冗余、提高工作 ......

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

前两章在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();
        }
    }
}

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

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

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