ASP.NET Core 2.2 WebApi 系列【六】泛型仓储模式
程序员文章站
2023-10-28 23:29:40
为什么要使用泛型仓储?好处是? 前两章在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(); } } }
运行项目执行接口,可以看到跟之前一样
如果有其他实体只需要改变传入的t就可以了,不需要再重新创建tentityrepository