驾一叶之扁舟 举匏樽以相属
寄蜉蝣于天地,渺沧海之一粟。哀吾生之须臾,羡长江之无穷。
挟飞仙以遨游,抱明月而长终。知不可乎骤得,托遗响于悲风。

从壹开始前后端分离【 .NET Core2.2/3.0 +Vue2.0 】框架之八 || API项目整体搭建 6.3 异步泛型仓储+依赖注入初探

本文3.0版本文章

本文涉及的内容,同样适用于3.0版本,不用修改。

 

回顾

1、Sqlsugar 的使用

  在上文中,遇到了大家见仁见智的评论和批评,嗯~说实话,积极性稍微受到了一丢丢的打击,不过还好,还是有很多很多很多人的赞同的,所以会一直坚持下去,欢迎提出各种建议,问题,意见等,我这个系列呢,只是一个抛砖引玉的文章,大家可以自定义的去扩展学习,比如你看了.net core api,可以自学.net core mvc呀;看了sqlsugar,可以自学EFCore,Deppar呀;看了vue,可以自学React、Angular呀,我希望起到的是一个志同道合的作用,而不是情绪的宣泄场所。🌹

  书接上文,《框架之七 || API项目整体搭建 6.2 轻量级ORM》,在文中,我们提到了Sqlsugar,该框架呢我也是咨询了身边的一些大佬,他们给我说法是:

Sqlsugar 和 EFCore 一样,只是一个表达式树,不用写sql,但是支持sql,支持多种类型数据库(MSSQL,Oracle,Mysql,SQLite),配置简单;

仅仅是一个数据访问层,100k轻量级,方便迁移;

而且也要看自己公司需要,我司项目也用EFCore ,当然也有部分用的是 SqlSugar,不存在孰优孰劣;

  关于速率呢,我简单的做了一个测试,使用公司的数据表,一共4千万条数据,我遍历全表,并提取前一万条(当然数据库有主键索引,一般分页100条也够多了吧),一共1.6s,截图如下:

 (从4千万数据中抽取1万条的整量数据到内存中,1.6s)

2、修改数据连接字符串

昨天也收到了很多人的问题和反馈,关于DbConfig连接字符串,@君子不器_万物有灵有新的方法,我很感谢他,把他的方法写出来

 可参考网文地址:配置和选项

1、在appsettings.json 中添加
"AppSettings": {
"SqlServerConnection": "Server=.;Database=BlogDB;User ID=sa;Password=sa;",
"ProviderName": "System.Data.SqlClient"
},

2、在 startup.cs 中的 ConfigureServices() 方法中添加
//数据库配置
BaseDBConfig.ConnectionString = Configuration.GetSection("AppSettings:SqlServerConnection").Value;

3、修改BaseDBConfig.cs
public static string ConnectionString { get; set; }

我在之后的项目中会使用他的这个方法,并且做一个扩展 Blog.Common 层 -> DB -> BaseDBConfig.cs  的 ,这里先封装上,如果大家都有好的意见或建议,我都会在下一篇文章中写出来,大家一起学习。

 好啦,昨天已经总结好了,开始今天的讲解。

 

在上一节中,我们实现了仓储层的构造,并联通了数据库,调取了数据,整理搭建已经有了一个雏形,今天就继续往下探讨,写一个异步泛型仓储

使用异步Async/Aswait呢,还是很方便的,不过,如果要使用异步,就要异步到底,不然就会阻塞,变成了同步,还是鼓励大家练习下,就算是出现错误了,那就证明学习到了,哈哈哈[哭笑];

泛型呢,用到的是接口和基类,可以极大的减少工作量;

 

 

今天要完成的浅紫色部分

 

 

 

一、设计仓储基类接口——IBaseRepository.cs

 

这里说一下,可能有一部分小伙伴是直接跳着看的,所以突然看到这里,对项目结构并不能很好的理解,可以参考之前的文章:《框架之六 || 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));
        }




    }


}
View Code

 

然后呢,同样在在Blog.Core.Repository 层中,将其他的接口,继承BaseRepository,这里略过,按下不表。

 

这里要说下,昨天有人问我DbContext.cs内容讲一下,其实呢,这个类里,很简单,主要是1、获取SqlSugarClient实例,2、CodeFirst(根据实体类生成数据库表);3、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);
        }

    }

}
View Code

 

 

五、运行项目,并调试接口

这个时候,需要把接口改成异步请求方式:

       // 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框架中,会自动生成。不过倘若有一个程序员把详情表实体类改错了,那订单表就崩溃了,哦不!我是遇到过这样的情景。

 

怎么解决这个问题呢,就出现了控制反转。网上看到一个挺好的讲解:

1、没有引入IOC之前,对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,A直接使用new关键字创建B的实例,程序高度耦合,效率低下,无论是创建还是使用B对象,控制权都在自己手上。

2、软件系统在引入IOC容器之后,这种情形就完全改变了,由于IOC容器的加入,对象A与对象B之间失去了直接联系,所以,当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B注入到对象A需要的地方。

3、依赖注入,是指程序运行过程中,如果需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部的注入。Spring的依赖注入对调用者和被调用者几乎没有任何要求,完全支持对POJO之间依赖关系的管理。依赖注入通常有两种:
·设值注入。
·构造注入。

这个就是依赖注入的方式。

什么是控制反转(IoC)


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的缓存等,慢慢来吧,给自己加加油!

 

八、CODE

 
https://github.com/anjoy8/Blog.Core.git

https://gitee.com/laozhangIsPhi/Blog.Core

 

posted @ 2018-08-24 14:00  老张的哲学  阅读(25768)  评论(79编辑  收藏  举报
作者:老张的哲学
好好学习,天天向上
返回顶部小火箭
好友榜:
如果愿意,把你的博客地址放这里
jianshu.com/u/老张
SqlSugar codeisbug.com