本文涉及的内容,一样适用于3.0版本,不用修改。html
在上文中,遇到了你们见仁见智的评论和批评,嗯~说实话,积极性稍微受到了一丢丢的打击,不过还好,仍是有不少不少不少人的赞同的,因此会一直坚持下去,欢迎提出各类建议,问题,意见等,我这个系列呢,只是一个抛砖引玉的文章,你们能够自定义的去扩展学习,好比你看了.net core api,能够自学.net core mvc呀;看了sqlsugar,能够自学EFCore,Deppar呀;看了vue,能够自学React、Angular呀,我但愿起到的是一个志同道合的做用,而不是情绪的宣泄场所。🌹vue
书接上文,《框架之七 || API项目总体搭建 6.2 轻量级ORM》,在文中,咱们提到了Sqlsugar,该框架呢我也是咨询了身边的一些大佬,他们给我说法是:git
Sqlsugar 和 EFCore 同样,只是一个表达式树,不用写sql,可是支持sql,支持多种类型数据库(MSSQL,Oracle,Mysql,SQLite),配置简单;程序员
仅仅是一个数据访问层,100k轻量级,方便迁移;github
并且也要看本身公司须要,我司项目也用EFCore ,固然也有部分用的是 SqlSugar,不存在孰优孰劣;sql
关于速率呢,我简单的作了一个测试,使用公司的数据表,一共4千万条数据,我遍历全表,并提取前一万条(固然数据库有主键索引,通常分页100条也够多了吧),一共1.6s,截图以下:数据库
(从4千万数据中抽取1万条的整量数据到内存中,1.6s)编程
昨天也收到了不少人的问题和反馈,关于DbConfig链接字符串,@君子不器_万物有灵有新的方法,我很感谢他,把他的方法写出来json
可参考网文地址:配置和选项后端
一、在appsettings.json 中添加 "AppSettings": { "SqlServerConnection": "Server=.;Database=BlogDB;User ID=sa;Password=sa;", "ProviderName": "System.Data.SqlClient" }, 二、在 startup.cs 中的 ConfigureServices() 方法中添加 //数据库配置 BaseDBConfig.ConnectionString = Configuration.GetSection("AppSettings:SqlServerConnection").Value; 三、修改BaseDBConfig.cs public static string ConnectionString { get; set; }
我在以后的项目中会使用他的这个方法,而且作一个扩展 Blog.Common 层 -> Helper -> Appsettings.cs 的 ,这里先写上,若是你们都有好的意见或建议,我都会在下一篇文章中写出来,你们一块儿学习。
好啦,昨天已经总结好了,开始今天的讲解。
在上一节中,咱们实现了仓储层的构造,并联通了数据库,调取了数据,整理搭建已经有了一个雏形,今天就继续往下探讨,写一个异步泛型仓储
使用异步Async/Aswait呢,仍是很方便的,不过,若是要使用异步,就要异步到底,否则就会阻塞,变成了同步,仍是鼓励你们练习下,就算是出现错误了,那就证实学习到了,哈哈哈[哭笑];
泛型呢,用到的是接口和基类,能够极大的减小工做量;
这里说一下,可能有一部分小伙伴是直接跳着看的,因此忽然看到这里,对项目结构并不能很好的理解,能够参考以前的文章:《框架之六 || API项目总体搭建 6.1 仓储+服务+抽象接口模式》
在Blog.Core.IRepository 层中添加BASE文件夹,并添加接口 IBaseRepository.cs
我本身从SimpleClient中,抽取了基本的常见方法作封装,你也能够本身自定义封装扩展,有人问我,既然Sqlsugar都已经封装好了SimpleClient,为何我还要在仓储中再一次封装,我是这么想的,若是一个项目中来了一个新人,以前用过EF或者Sqlhelper,那他来了,须要在从新学习一遍Sqlsugar了,这个时间上,至少一两天吧,因此封装基本的接口后,他只须要按照以前的开发方法使用就行,不须要了解底层,固然这个仍是个小栗子,其实大公司都是这样的,更新迭代很快,没有精力从新学习,因此这也就是面向接口编程的好处,我曾经在微软的项目中就充分的感觉到这个境况。
注意:我这里没有封装多表查询,实际上是能够写的,参考地址 多表查询, ,若是各位会封装的话,能够留言,感激涕零。
public interface IBaseRepository<TEntity> where TEntity : class { Task<TEntity> QueryByID(object objId); Task<TEntity> QueryByID(object objId, bool blnUseCache = false); Task<List<TEntity>> QueryByIDs(object[] lstIds); Task<int> Add(TEntity model); Task<bool> DeleteById(object id); Task<bool> Delete(TEntity model); Task<bool> DeleteByIds(object[] ids); Task<bool> Update(TEntity model); Task<bool> Update(TEntity entity, string strWhere); Task<bool> Update(TEntity entity, List<string> lstColumns = null, List<string> lstIgnoreColumns = null, string strWhere = ""); Task<List<TEntity>> Query(); Task<List<TEntity>> Query(string strWhere); Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression); Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, string strOrderByFileds); Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression, bool isAsc = true); Task<List<TEntity>> Query(string strWhere, string strOrderByFileds); Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, int intTop, string strOrderByFileds); Task<List<TEntity>> Query(string strWhere, int intTop, string strOrderByFileds); Task<List<TEntity>> Query( Expression<Func<TEntity, bool>> whereExpression, int intPageIndex, int intPageSize , string strOrderByFileds); Task<List<TEntity>> Query(string strWhere, int intPageIndex, int intPageSize , string strOrderByFileds); Task<List<TEntity>> QueryPage(Expression<Func<TEntity, bool>> whereExpression, int intPageIndex = 0, int intPageSize = 20, string strOrderByFileds = null); }
在Blog.Core.IRepository 层中,将其余的接口,继承Base。
还记得前几天咱们一直用的IAdvertisementRepository.cs么,终于能够写到自身代码了,继承Base
而后将其余全部的方法都继承该基类方法,不细说,能够去Github查看。
在Blog.Core.Repository 层中,添加BASE文件夹,并添加 BaseRepository.cs 基类
基本写法和前几天的AdvertisementRepository.cs很相似,代码以下:
//BaseRepository.cs
namespace Blog.Core.Repository.Base { public class BaseRepository<TEntity> : IBaseRepository<TEntity> where TEntity : class, new() { private DbContext context; private SqlSugarClient db; private SimpleClient<TEntity> entityDB; public DbContext Context { get { return context; } set { context = value; } } internal SqlSugarClient Db { get { return db; } private set { db = value; } } internal SimpleClient<TEntity> EntityDB { get { return entityDB; } private set { entityDB = value; } } public BaseRepository() { DbContext.Init(BaseDBConfig.ConnectionString); context = DbContext.GetDbContext(); db = context.Db; entityDB = context.GetEntityDB<TEntity>(db); } public async Task<TEntity> QueryByID(object objId) { return await Task.Run(() => db.Queryable<TEntity>().InSingle(objId)); } /// <summary> /// 功能描述:根据ID查询一条数据 /// 做 者:Blog.Core /// </summary> /// <param name="objId">id(必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]),若是是联合主键,请使用Where条件</param> /// <param name="blnUseCache">是否使用缓存</param> /// <returns>数据实体</returns> public async Task<TEntity> QueryByID(object objId, bool blnUseCache = false) { return await Task.Run(() => db.Queryable<TEntity>().WithCacheIF(blnUseCache).InSingle(objId)); } /// <summary> /// 功能描述:根据ID查询数据 /// 做 者:Blog.Core /// </summary> /// <param name="lstIds">id列表(必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]),若是是联合主键,请使用Where条件</param> /// <returns>数据实体列表</returns> public async Task<List<TEntity>> QueryByIDs(object[] lstIds) { return await Task.Run(() => db.Queryable<TEntity>().In(lstIds).ToList()); } /// <summary> /// 写入实体数据 /// </summary> /// <param name="entity">博文实体类</param> /// <returns></returns> public async Task<int> Add(TEntity entity) { var i = await Task.Run(() => db.Insertable(entity).ExecuteReturnBigIdentity()); //返回的i是long类型,这里你能够根据你的业务须要进行处理 return (int)i; } /// <summary> /// 更新实体数据 /// </summary> /// <param name="entity">博文实体类</param> /// <returns></returns> public async Task<bool> Update(TEntity entity) { //这种方式会以主键为条件 var i = await Task.Run(() => db.Updateable(entity).ExecuteCommand()); return i > 0; } public async Task<bool> Update(TEntity entity, string strWhere) { return await Task.Run(() => db.Updateable(entity).Where(strWhere).ExecuteCommand() > 0); } public async Task<bool> Update(string strSql, SugarParameter[] parameters = null) { return await Task.Run(() => db.Ado.ExecuteCommand(strSql, parameters) > 0); } public async Task<bool> Update( TEntity entity, List<string> lstColumns = null, List<string> lstIgnoreColumns = null, string strWhere = "" ) { IUpdateable<TEntity> up = await Task.Run(() => db.Updateable(entity)); if (lstIgnoreColumns != null && lstIgnoreColumns.Count > 0) { up = await Task.Run(() => up.IgnoreColumns(it => lstIgnoreColumns.Contains(it))); } if (lstColumns != null && lstColumns.Count > 0) { up = await Task.Run(() => up.UpdateColumns(it => lstColumns.Contains(it))); } if (!string.IsNullOrEmpty(strWhere)) { up = await Task.Run(() => up.Where(strWhere)); } return await Task.Run(() => up.ExecuteCommand()) > 0; } /// <summary> /// 根据实体删除一条数据 /// </summary> /// <param name="entity">博文实体类</param> /// <returns></returns> public async Task<bool> Delete(TEntity entity) { var i = await Task.Run(() => db.Deleteable(entity).ExecuteCommand()); return i > 0; } /// <summary> /// 删除指定ID的数据 /// </summary> /// <param name="id">主键ID</param> /// <returns></returns> public async Task<bool> DeleteById(object id) { var i = await Task.Run(() => db.Deleteable<TEntity>(id).ExecuteCommand()); return i > 0; } /// <summary> /// 删除指定ID集合的数据(批量删除) /// </summary> /// <param name="ids">主键ID集合</param> /// <returns></returns> public async Task<bool> DeleteByIds(object[] ids) { var i = await Task.Run(() => db.Deleteable<TEntity>().In(ids).ExecuteCommand()); return i > 0; } /// <summary> /// 功能描述:查询全部数据 /// 做 者:Blog.Core /// </summary> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query() { return await Task.Run(() => entityDB.GetList()); } /// <summary> /// 功能描述:查询数据列表 /// 做 者:Blog.Core /// </summary> /// <param name="strWhere">条件</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query(string strWhere) { return await Task.Run(() => db.Queryable<TEntity>().WhereIF(!string.IsNullOrEmpty(strWhere), strWhere).ToList()); } /// <summary> /// 功能描述:查询数据列表 /// 做 者:Blog.Core /// </summary> /// <param name="whereExpression">whereExpression</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression) { return await Task.Run(() => entityDB.GetList(whereExpression)); } /// <summary> /// 功能描述:查询一个列表 /// 做 者:Blog.Core /// </summary> /// <param name="whereExpression">条件表达式</param> /// <param name="strOrderByFileds">排序字段,如name asc,age desc</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, string strOrderByFileds) { return await Task.Run(() => db.Queryable<TEntity>().OrderByIF(!string.IsNullOrEmpty(strOrderByFileds), strOrderByFileds).WhereIF(whereExpression != null, whereExpression).ToList()); } /// <summary> /// 功能描述:查询一个列表 /// </summary> /// <param name="whereExpression"></param> /// <param name="orderByExpression"></param> /// <param name="isAsc"></param> /// <returns></returns> public async Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression, bool isAsc = true) { return await Task.Run(() => db.Queryable<TEntity>().OrderByIF(orderByExpression != null, orderByExpression, isAsc ? OrderByType.Asc : OrderByType.Desc).WhereIF(whereExpression != null, whereExpression).ToList()); } /// <summary> /// 功能描述:查询一个列表 /// 做 者:Blog.Core /// </summary> /// <param name="strWhere">条件</param> /// <param name="strOrderByFileds">排序字段,如name asc,age desc</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query(string strWhere, string strOrderByFileds) { return await Task.Run(() => db.Queryable<TEntity>().OrderByIF(!string.IsNullOrEmpty(strOrderByFileds), strOrderByFileds).WhereIF(!string.IsNullOrEmpty(strWhere), strWhere).ToList()); } /// <summary> /// 功能描述:查询前N条数据 /// 做 者:Blog.Core /// </summary> /// <param name="whereExpression">条件表达式</param> /// <param name="intTop">前N条</param> /// <param name="strOrderByFileds">排序字段,如name asc,age desc</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query( Expression<Func<TEntity, bool>> whereExpression, int intTop, string strOrderByFileds) { return await Task.Run(() => db.Queryable<TEntity>().OrderByIF(!string.IsNullOrEmpty(strOrderByFileds), strOrderByFileds).WhereIF(whereExpression != null, whereExpression).Take(intTop).ToList()); } /// <summary> /// 功能描述:查询前N条数据 /// 做 者:Blog.Core /// </summary> /// <param name="strWhere">条件</param> /// <param name="intTop">前N条</param> /// <param name="strOrderByFileds">排序字段,如name asc,age desc</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query( string strWhere, int intTop, string strOrderByFileds) { return await Task.Run(() => db.Queryable<TEntity>().OrderByIF(!string.IsNullOrEmpty(strOrderByFileds), strOrderByFileds).WhereIF(!string.IsNullOrEmpty(strWhere), strWhere).Take(intTop).ToList()); } /// <summary> /// 功能描述:分页查询 /// 做 者:Blog.Core /// </summary> /// <param name="whereExpression">条件表达式</param> /// <param name="intPageIndex">页码(下标0)</param> /// <param name="intPageSize">页大小</param> /// <param name="intTotalCount">数据总量</param> /// <param name="strOrderByFileds">排序字段,如name asc,age desc</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query( Expression<Func<TEntity, bool>> whereExpression, int intPageIndex, int intPageSize, string strOrderByFileds) { return await Task.Run(() => db.Queryable<TEntity>().OrderByIF(!string.IsNullOrEmpty(strOrderByFileds), strOrderByFileds).WhereIF(whereExpression != null, whereExpression).ToPageList(intPageIndex, intPageSize)); } /// <summary> /// 功能描述:分页查询 /// 做 者:Blog.Core /// </summary> /// <param name="strWhere">条件</param> /// <param name="intPageIndex">页码(下标0)</param> /// <param name="intPageSize">页大小</param> /// <param name="intTotalCount">数据总量</param> /// <param name="strOrderByFileds">排序字段,如name asc,age desc</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query( string strWhere, int intPageIndex, int intPageSize, string strOrderByFileds) { return await Task.Run(() => db.Queryable<TEntity>().OrderByIF(!string.IsNullOrEmpty(strOrderByFileds), strOrderByFileds).WhereIF(!string.IsNullOrEmpty(strWhere), strWhere).ToPageList(intPageIndex, intPageSize)); } public async Task<List<TEntity>> QueryPage(Expression<Func<TEntity, bool>> whereExpression, int intPageIndex = 0, int intPageSize = 20, string strOrderByFileds = null) { return await Task.Run(() => db.Queryable<TEntity>() .OrderByIF(!string.IsNullOrEmpty(strOrderByFileds), strOrderByFileds) .WhereIF(whereExpression != null, whereExpression) .ToPageList(intPageIndex, intPageSize)); } } }
而后呢,一样在在Blog.Core.Repository 层中,将其余的接口,继承BaseRepository,这里略过,按下不表。
这里要说下,昨天有人问我DbContext.cs内容讲一下,其实呢,这个类里,很简单,主要是一、获取SqlSugarClient实例,二、CodeFirst(根据实体类生成数据库表);三、DbFirst(根据数据库表生成实体类)。只不过都是用到的同名方法重载,可能看上去比较累,能够调用一次就能明白了。
这里简单说下DbFirst吧,其余的能够自行研究下,也能够右侧扫码加QQ群,咱们一对一讨论。DbFirst是一个根据数据库表生成实体类的过程,前提是要有系统表的权限,不然没法读取表的结构,框架在底层封装了不少模板,将真实值填充进去,特别像是动软代码生成器或者T4模板。
一样在Blog.Core.IServices 和 Blog.Core.Services 层中,分别添加基接口,并实现基类
public interface IBaseServices<TEntity> where TEntity : class { Task<TEntity> QueryByID(object objId); Task<TEntity> QueryByID(object objId, bool blnUseCache = false); Task<List<TEntity>> QueryByIDs(object[] lstIds); Task<int> Add(TEntity model); Task<bool> DeleteById(object id); Task<bool> Delete(TEntity model); Task<bool> DeleteByIds(object[] ids); Task<bool> Update(TEntity model); Task<bool> Update(TEntity entity, string strWhere); Task<bool> Update(TEntity entity, List<string> lstColumns = null, List<string> lstIgnoreColumns = null, string strWhere = ""); Task<List<TEntity>> Query(); Task<List<TEntity>> Query(string strWhere); Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression); Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, string strOrderByFileds); Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression, bool isAsc = true); Task<List<TEntity>> Query(string strWhere, string strOrderByFileds); Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, int intTop, string strOrderByFileds); Task<List<TEntity>> Query(string strWhere, int intTop, string strOrderByFileds); Task<List<TEntity>> Query( Expression<Func<TEntity, bool>> whereExpression, int intPageIndex, int intPageSize, string strOrderByFileds); Task<List<TEntity>> Query(string strWhere, int intPageIndex, int intPageSize, string strOrderByFileds); Task<List<TEntity>> QueryPage(Expression<Func<TEntity, bool>> whereExpression, int intPageIndex = 0, int intPageSize = 20, string strOrderByFileds = null); }
//BaseServices.cs
namespace Blog.Core.Services.BASE { public class BaseServices<TEntity> : IBaseServices<TEntity> where TEntity : class, new() { public IBaseRepository<TEntity> baseDal = new BaseRepository<TEntity>(); public async Task<TEntity> QueryByID(object objId) { return await baseDal.QueryByID(objId); } /// <summary> /// 功能描述:根据ID查询一条数据 /// 做 者:AZLinli.Blog.Core /// </summary> /// <param name="objId">id(必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]),若是是联合主键,请使用Where条件</param> /// <param name="blnUseCache">是否使用缓存</param> /// <returns>数据实体</returns> public async Task<TEntity> QueryByID(object objId, bool blnUseCache = false) { return await baseDal.QueryByID(objId, blnUseCache); } /// <summary> /// 功能描述:根据ID查询数据 /// 做 者:AZLinli.Blog.Core /// </summary> /// <param name="lstIds">id列表(必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]),若是是联合主键,请使用Where条件</param> /// <returns>数据实体列表</returns> public async Task<List<TEntity>> QueryByIDs(object[] lstIds) { return await baseDal.QueryByIDs(lstIds); } /// <summary> /// 写入实体数据 /// </summary> /// <param name="entity">博文实体类</param> /// <returns></returns> public async Task<int> Add(TEntity entity) { return await baseDal.Add(entity); } /// <summary> /// 更新实体数据 /// </summary> /// <param name="entity">博文实体类</param> /// <returns></returns> public async Task<bool> Update(TEntity entity) { return await baseDal.Update(entity); } public async Task<bool> Update(TEntity entity, string strWhere) { return await baseDal.Update(entity, strWhere); } public async Task<bool> Update( TEntity entity, List<string> lstColumns = null, List<string> lstIgnoreColumns = null, string strWhere = "" ) { return await baseDal.Update(entity, lstColumns, lstIgnoreColumns, strWhere); } /// <summary> /// 根据实体删除一条数据 /// </summary> /// <param name="entity">博文实体类</param> /// <returns></returns> public async Task<bool> Delete(TEntity entity) { return await baseDal.Delete(entity); } /// <summary> /// 删除指定ID的数据 /// </summary> /// <param name="id">主键ID</param> /// <returns></returns> public async Task<bool> DeleteById(object id) { return await baseDal.DeleteById(id); } /// <summary> /// 删除指定ID集合的数据(批量删除) /// </summary> /// <param name="ids">主键ID集合</param> /// <returns></returns> public async Task<bool> DeleteByIds(object[] ids) { return await baseDal.DeleteByIds(ids); } /// <summary> /// 功能描述:查询全部数据 /// 做 者:AZLinli.Blog.Core /// </summary> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query() { return await baseDal.Query(); } /// <summary> /// 功能描述:查询数据列表 /// 做 者:AZLinli.Blog.Core /// </summary> /// <param name="strWhere">条件</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query(string strWhere) { return await baseDal.Query(strWhere); } /// <summary> /// 功能描述:查询数据列表 /// 做 者:AZLinli.Blog.Core /// </summary> /// <param name="whereExpression">whereExpression</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression) { return await baseDal.Query(whereExpression); } /// <summary> /// 功能描述:查询一个列表 /// 做 者:AZLinli.Blog.Core /// </summary> /// <param name="whereExpression">条件表达式</param> /// <param name="strOrderByFileds">排序字段,如name asc,age desc</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression, bool isAsc = true) { return await baseDal.Query(whereExpression, orderByExpression, isAsc); } public async Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, string strOrderByFileds) { return await baseDal.Query(whereExpression, strOrderByFileds); } /// <summary> /// 功能描述:查询一个列表 /// 做 者:AZLinli.Blog.Core /// </summary> /// <param name="strWhere">条件</param> /// <param name="strOrderByFileds">排序字段,如name asc,age desc</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query(string strWhere, string strOrderByFileds) { return await baseDal.Query(strWhere, strOrderByFileds); } /// <summary> /// 功能描述:查询前N条数据 /// 做 者:AZLinli.Blog.Core /// </summary> /// <param name="whereExpression">条件表达式</param> /// <param name="intTop">前N条</param> /// <param name="strOrderByFileds">排序字段,如name asc,age desc</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, int intTop, string strOrderByFileds) { return await baseDal.Query(whereExpression, intTop, strOrderByFileds); } /// <summary> /// 功能描述:查询前N条数据 /// 做 者:AZLinli.Blog.Core /// </summary> /// <param name="strWhere">条件</param> /// <param name="intTop">前N条</param> /// <param name="strOrderByFileds">排序字段,如name asc,age desc</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query( string strWhere, int intTop, string strOrderByFileds) { return await baseDal.Query(strWhere, intTop, strOrderByFileds); } /// <summary> /// 功能描述:分页查询 /// 做 者:AZLinli.Blog.Core /// </summary> /// <param name="whereExpression">条件表达式</param> /// <param name="intPageIndex">页码(下标0)</param> /// <param name="intPageSize">页大小</param> /// <param name="intTotalCount">数据总量</param> /// <param name="strOrderByFileds">排序字段,如name asc,age desc</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query( Expression<Func<TEntity, bool>> whereExpression, int intPageIndex, int intPageSize, string strOrderByFileds) { return await baseDal.Query( whereExpression, intPageIndex, intPageSize, strOrderByFileds); } /// <summary> /// 功能描述:分页查询 /// 做 者:AZLinli.Blog.Core /// </summary> /// <param name="strWhere">条件</param> /// <param name="intPageIndex">页码(下标0)</param> /// <param name="intPageSize">页大小</param> /// <param name="intTotalCount">数据总量</param> /// <param name="strOrderByFileds">排序字段,如name asc,age desc</param> /// <returns>数据列表</returns> public async Task<List<TEntity>> Query( string strWhere, int intPageIndex, int intPageSize, string strOrderByFileds) { return await baseDal.Query( strWhere, intPageIndex, intPageSize, strOrderByFileds); } public async Task<List<TEntity>> QueryPage(Expression<Func<TEntity, bool>> whereExpression, int intPageIndex = 0, int intPageSize = 20, string strOrderByFileds = null) { return await baseDal.QueryPage(whereExpression, intPageIndex = 0, intPageSize, strOrderByFileds); } } }
这个时候,须要把接口改为异步请求方式:
// GET: api/Blog/5 /// <summary> /// 根据id获取数据 /// </summary> /// <param name="id">参数id</param> /// <returns></returns> [HttpGet("{id}", Name = "Get")] public async Task<List<Advertisement>> Get(int id) { IAdvertisementServices advertisementServices = new AdvertisementServices(); return await advertisementServices.Query(d => d.Id == id); }
Http返回200,一切正常。
首先,咱们须要了解下什么是控制反转IOC,举个栗子,我在以前开发简单商城的时候,其中呢,订单模块,有订单表,那里边确定有订单详情表,并且呢订单详情表中还有商品信息表,商品信息表还关联了价格规格表,或者其余的物流信息,商家信息,固然,咱们能够放到一个大表里,但是你必定不会这么作,由于太庞大,因此一定分表,那一定会出现类中套类的局面,这就是依赖,好比上边的,订单表就依赖了详情表,咱们在实例化订单实体类的时候,也须要手动实例详情表,固然,EF框架中,会自动生成。不过假若有一个程序员把详情表实体类改错了,那订单表就崩溃了,哦不!我是遇到过这样的情景。
怎么解决这个问题呢,就出现了控制反转。网上看到一个挺好的讲解:
一、没有引入IOC以前,对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,A直接使用new关键字建立B的实例,程序高度耦合,效率低下,不管是建立仍是使用B对象,控制权都在本身手上。
二、软件系统在引入IOC容器以后,这种情形就彻底改变了,因为IOC容器的加入,对象A与对象B之间失去了直接联系,因此,当对象A运行到须要对象B的时候,IOC容器会主动建立一个对象B注入到对象A须要的地方。
三、依赖注入,是指程序运行过程当中,若是须要调用另外一个对象协助时,无须在代码中建立被调用者,而是依赖于外部的注入。Spring的依赖注入对调用者和被调用者几乎没有任何要求,彻底支持对POJO之间依赖关系的管理。依赖注入一般有两种:
·设值注入。
·构造注入。这个就是依赖注入的方式。
Inversion of Control,英文缩写为IoC,不是什么技术,而是一种设计思想。
简单来讲就是把复杂系统分解成相互合做的对象,这些对象类经过封装之后,内部实现对外部是透明的,从而下降了解决问题的复杂度,并且能够灵活地被重用和扩展。IOC理论提出的观点大致是这样的:借助于“第三方”实现具备依赖关系的对象之间的解耦,以下图:
你们看到了吧,因为引进了中间位置的“第三方”,也就是IOC容器,使得A、B、C、D这4个对象没有了耦合关系,齿轮之间的传动所有依靠“第三方”了,所有对象的控制权所有上缴给“第三方”IOC容器,因此,IOC容器成了整个系统的关键核心,它起到了一种相似“黏合剂”的做用,把系统中的全部对象粘合在一块儿发挥做用,若是没有这个“黏合剂”,对象与对象之间会彼此失去联系,这就是有人把IOC容器比喻成“黏合剂”的由来。
咱们再来作个试验:把上图中间的IOC容器拿掉,而后再来看看这套系统:
咱们如今看到的画面,就是咱们要实现整个系统所须要完成的所有内容。这时候,A、B、C、D这4个对象之间已经没有了耦合关系,彼此毫无联系,这样的话,当你在实现A的时候,根本无须再去考虑B、C和D了,对象之间的依赖关系已经下降到了最低程度。因此,若是真能实现IOC容器,对于系统开发而言,这将是一件多么美好的事情,参与开发的每一成员只要实现本身的类就能够了,跟别人没有任何关系!
由于时间和篇幅的关系,今天在项目中,暂时不引入Autofac了,下周咱们继续深刻了解。
写文章原来也是一个体力活,嗯加油!今天终于将后端框架补充了下,实现了基本的功能,重点讲解了如何在仓储模式中,使用基类泛型,固然这是一个思想,你也能够在开发的过程当中,多使用抽象类,接口编程;
而后呢,又简单的使用了异步编程,如今也是很流行的一直写法,我也是刚使用,你们欢迎批评指正;
简单的了解了下,IOC控制反转和DI依赖注入,为下次作准备;
固然,如今才仅仅是一个雏形,之后还会用到AOP的日志,异常记录;Redis的缓存等,慢慢来吧,给本身加加油!