手擼ORM淺談ORM框架之Query篇
快速傳送
手擼ORM淺談ORM框架之基礎篇
手擼ORM淺談ORM框架之Add篇
手擼ORM淺談ORM框架之Update篇
手擼ORM淺談ORM框架之Delete篇
手擼ORM淺談ORM框架之Query篇
後續待定。。。。。。
姍姍來遲結尾
最近瑣事纏身本應該上週就更新的文章,硬生生的拖到今天。實在抱歉,實在抱歉,實在抱歉!!!近期也不斷為自己的職業生涯思考,兩條路選擇:技術路線?還是管理路線?不僅對自己目前狀態進行深刻思考,還計劃後面一段時間學習閱讀優秀開源專案原始碼。
從前的少年
在<手擼ORM淺談ORM框架之Add篇>提過微軟提供了 基本原生 SQL 查詢 可使用 FromSqlRaw 擴充套件方法基於原始 SQL 查詢開始 LINQ 查詢, FromSqlRaw 只能在直接位於 DbSet<> 上的查詢根上使用;Query基類方法封裝時,傳入 SELECT COLUMN NAME FROM TABLENAME WHERE id=@id, parameters 或 string.Format("SELECT COLUMN NAME FROM TABLENAME WHERE id=[0]",id) 就遇到了 "Input string was not in a correct format." ,嘗試多種引數均以失敗告終;被迫最後轉戰ADO.NET原汁原味實現泛型查詢。
ADO.NET食用
(NET程式設計師必備法器) ADO.NET通過ADO.NET DataSet介面提供,包括一些與提供者層進行互動的元件,五大物件分別是:- Connection (連線資料庫)
- Command (執行T-SQL語句)
- DataAdapter (使用者填充DataSet,斷開模式)
- DataReader (讀取資料庫,一種只讀模式,只向前的)
- DataSet (資料集,好比電腦的記憶體)
.NET本質連線資料庫,就是ADO.NET連線資料庫、讀取、刪除、修改資料。(ADO.NET詳細使用就不在本文贅述,部落格園有很多相關優秀的文章)
吃老婆本
BaseRepository-》GetCurrentTableName已經在《手擼ORM淺談ORM框架之Add篇》BaseRepository裡面的方法,不重複搬磚了。
自食其力
封裝SqlQuery方法的基礎工作是我們需要什麼的樣的Sql SELECT查詢語句,我們先來看看SELECT語句結構: SELECT COLUMN NAME FROM TABLENAME ,以單個簡單實體查詢的Sql SELECT語句實操;
BaseRepository-》GetQuerySql;
1 /// <summary> 2 /// get query sql 3 /// </summary> 4 /// <returns></returns> 5 private string GetQuerySql() 6 { 7 string tableName = GetCurrentTableName(); 8 PropertyInfo[] propertyInfos = typeof(T).GetProperties(); 9 StringBuilder stringBuilder = new StringBuilder(); 10 foreach (var item in propertyInfos) 11 { 12 stringBuilder.AppendFormat("{0},", item.Name); 13 } 14 return string.Format("SELECT {0} FROM {1} ", stringBuilder.Remove(stringBuilder.Length - 1, 1), tableName); 15 }
ADO.NET xxxSql用來執行查詢資料Sql;
1 /// <summary> 2 /// query sql return datatable 3 /// </summary> 4 /// <param name="sql">sql</param> 5 /// <returns></returns> 6 public DataTable ExecuteDataTable(string sql) 7 { 8 using (MySqlConnection connection = new MySqlConnection(connectionString)) 9 { 10 DataTable dt = new DataTable(); 11 try 12 { 13 connection.Open(); 14 MySqlDataAdapter command = new MySqlDataAdapter(sql, connection); 15 command.Fill(dt); 16 } 17 catch (SqlException ex) 18 { 19 throw new Exception(ex.Message); 20 } 21 return dt; 22 } 23 }
BaseRepository-》DataTableToT,DataTable轉換當前實體需要的型別(泛型方法);
1 /// <summary> 2 /// datatable to t 3 /// </summary> 4 /// <param name="dataTable">dataTable</param> 5 /// <returns>return t</returns> 6 private T DataTableToT(DataTable dataTable) 7 { 8 var propertyInfos = typeof(T).GetProperties(); 9 foreach (DataRow row in dataTable.Rows) 10 { 11 T t = new T(); 12 foreach (PropertyInfo p in propertyInfos) 13 { 14 //型別需要做轉換bool char 15 if (p.PropertyType.Name == nameof(Boolean)) 16 { 17 p.SetValue(t, Convert.ToBoolean(row[p.Name])); 18 } 19 else 20 { 21 p.SetValue(t, row[p.Name] is DBNull ? null : row[p.Name]); 22 } 23 } 24 return t; 25 } 26 return default(T); 27 }
實操BaseRepository-》Get根據id獲取實體,主鍵暫時使用bigint型別id;查詢條件使用lambda條件可以增加查詢的靈活性(推薦使用這種方法);
1 /// <summary> 2 /// get entity 3 /// </summary> 4 /// <param name="id">id</param> 5 /// <returns>return entity</returns> 6 public T Get(long id) 7 { 8 string sql = string.Format("{0} WHERE {1}={2} LIMIT 1", GetQuerySql(), nameof(id), id); 9 return SqlQuery(sql); 10 //string sql = string.Format("{0} WHERE {1}=@{1}", GetQuerySql(), id); 11 //return SqlQuery(sql, new[] { new MySqlParameter(string.Format("@{0}",id), id) }); 12 }
尾聲
手擼ORM淺談ORM框架系列專案簡易版ORM並不建議直接放在專案中使用,僅推薦除學習ORM原理需求者。專案中並沒有很好地滿足常規業務需要,例如:實體導航屬性、主子表先後順序等複雜實體,增刪查改均未實現;並且還有很多待優化的地方,例如:快取的使用、Sql語句的查詢優化等等。
獲獎感言Finish
自從決定寫手擼ORM淺談ORM框架系列,每一篇都反覆的檢查和修改,內容儘量提煉通俗易懂,把自己理解的完整的表述出來實屬不易。文章中或許還存在不足,詞不達意的地方請閱讀者多多包涵。註冊部落格快三年了,畢業轉眼間也三年多了,自從2018年1月8號到北京工作已有1039天了,一個普普通的本科畢業未經過培訓結構的洗禮,偶爾蹭蹭公開課(最愛大B站: https://www.bilibili.com、部落格園: https://www.cnblogs.com、Github: https://github.com),技術是一點一滴的積攢出來的,對有些定義的理解、表達可能有些詞不達意,請閱讀者多多包涵!
注:learn-orm-net目前只是作為學習ORM框架原理的Demo,專案會做出一定的優化處理,但不能直接拿來在專案中使用,畢竟現在NET Framework、NET Core已經有很多優秀的ORM框架,NET下一次釋出就是隻有一個版本了,NET5已經發布了,我們沒有必要重複造輪子,造輪子是因為沒有現成的優秀的輪子可用。
程式碼下載地址: SourceCode 作者水平有限歡迎園友糾正錯誤及不恰當之處,予以及時修正以免誤導他