快速傳送
後續待定。。。。。。
姍姍來遲結尾
最近瑣事纏身本應該上週就更新的文章,硬生生的拖到今天。實在抱歉,實在抱歉,實在抱歉!!!近期也不斷為自己的職業生涯思考,兩條路選擇:技術路線?還是管理路線?不僅對自己目前狀態進行深刻思考,還計劃後面一段時間學習閱讀優秀開源專案原始碼。
從前的少年
在<手擼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程式設計師必備法器)- 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 作者水平有限歡迎園友糾正錯誤及不恰當之處,予以及時修正以免誤導他人!