本文涉及的內容,一樣適用於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的緩存等,慢慢來吧,給本身加加油!