Newlife.XCode的查詢與資料初始化功能介紹

solution發表於2021-09-09

1.前言

  使用XCode已經3年了,談不上精通,都是些基礎功能使用,以前原始碼啃過很多次,瞭解過部分功能的實現細節,但終歸是要應用的,當沒有時間時,瞭解使用就可以了,所以現在更多關注業務相關的東西,資料庫操作,XCode已經很完善了。本文就對這幾年應用過程的一些問題,以及很多人經常問起來的問題進行一個總結。今天就介紹2個主要的,比較常見的使用:表示式查詢,實體資料初始化。

  我們將在下一篇部落格中重點介紹更加重量級的分庫分表功能,以及通用配置輔助類的使用。敬請關注。

 如果文章或者資源對您有用,請“推薦”和關注,接下來還有很多.NET平臺關於機器學習、彩票分析平臺和預測的文章和資源待發表。


2.簡潔優雅的查詢

  XCode對查詢語法和靈活性是我見過的ORM中最優雅的,最簡單體貼的。XCode由於支援多種資料庫,並且效率很高的原因就是在這些資料庫核心操作的背後有許多精巧的設計,其支援的查詢就是XCode靈活強大的表現之一,每天寫著重複的sql,除錯,拼接引數,真的很累,那麼看看XCode中的查詢,真的是賞心悅目,是一種享受吧。首先對XCode的查詢語法進行一個簡單的總結和描述:

1 var model1 = Find(_.Name, "中國");
2 //下面2個結果是一樣的,用的方法不一樣
3 var model2 = Find(new String[] { _.Name, _.OnceName }, new object[] {"中國","China" });
4 var model3 = Find(_.Name == "中國" & _.OnceName == "China");
5 //同理看一個FindAll的使用
6 var modelList1 = FindAll(_.IsAsia, true);//只針對IsAsia欄位
7 //FindAll的最常見使用:5個引數的,第一個是條件表示式,第二個是排序欄位(ComanyID),第三個是選擇的欄位,null代表選擇所有
8 //startIndex引數,代表起始行,預設都是從0開始,最後一個表示放回的資料行數,0代表所有行,可以只取前10。
9 var modelList2 = FindAll(_.IsAsia == true & _.IsAuthority == true, _.ComanyID, null, 0, 0);


 2) XCode的查詢是實體基類Entity封裝好的靜態方法,裡面包含很多東西,建議熟練使用後的朋友,好好看一看,對理解XCode,更好的使用都有很大的好處。

3) XCode中查詢滿足條件的記錄數有專門的FindCount方法;其方法原型和FindAll類似。

4) XCode有著非常完善的快取體系,實體類是直接可以進行快取設定和查詢的,方法是FindAllWithCache; Meta.Cache.Entities中也有快取資料,可以直接查詢。例如: 

1 // 實體快取
2 Meta.Cache.Entities.FindAll(_.EventId, eventid);
3 Meta.Cache.Entities.Find(_.Id, id);
4 //單物件快取
5 return Meta.SingleCache[id];
6 FindAllWithCache(_.EventName, "西甲");

 5) XCode的實體操作介面IEntityOperate中也有相對於的查詢方法,使用與單個實體的Find和FindAll的使用基本相同。例如下面一段程式碼(2年前使用XCode遷移資料寫的,非常好理解,也非常好的完成了遷移工作)。裡面在對錶進行處理的時候,就使用了IEntityOperate來操作,非常方便。其使用和原理可以看原始碼,和部落格的其他文章。 

1 /// 
 2 /// 複製資料庫,只需要資料庫連線字串和源資料庫即可
 3 /// 
 4 /// 源資料庫連線字串
 5 /// 目的資料庫連線字串
 6 /// 每次獲取的記錄數目,如果預設-1則會自動呼叫函式計算一個合理值
 7 public static void CopyDataBase(string originConn,string desConn,int perCount = -1)
 8 {
 9     //思路:透過源資料庫獲取架構資訊,然後反向工程,然後匯出資料            
10     DAL dal = DAL.Create(originConn);
11     List tableList = dal.Tables;//獲取源資料庫的架構資訊
12     tableList.RemoveAll(t => t.IsView);//過濾掉檢視
13     //首先複製資料庫架構            
14     DAL desDal = DAL.Create(desConn);//要在配置檔案中啟用資料庫架構才行 
15     desDal.Db.CreateMetaData().SetTables(tableList.ToArray());               
16     //然後依次複製每個表中的資料
17     foreach (var item in tableList)
18     {
19         //首先根據表名稱獲取當前表的實體操作介面
20         IEntityOperate Factory = dal.CreateOperate(item.Name);
21         //分頁獲取資料,並更新到新的資料庫,透過更改資料庫連線來完成
22         int allCount = Factory.FindCount ();
23         if (perCount 

  

6) XCode中的查詢表示式型別是 WhereExpression,實際中的SQL語句拼接的結果就是WhereExpression型別,而該型別的拼接支援 &,| 運算子的過載,可以直接將不同的條件組合在一起。拼接的欄位名稱為XX._.欄位名,_的實體型別的用處也主要在這裡,注意WhereExpression型別是可以隱式轉換為String型別的。這也是為什麼有人不解直接將WhereExpression型別放入FindAll第一個引數的原因,其實已經轉換成String了。看看1個實際查詢綜合的例子(來源於大石頭BBX專案中的程式碼):  

 1 /// 獲取有效的廣告列表
 2 public static EntityList GetAvailableList()
 3 {
 4     //return FindAll(_.StartTime  DateTime.Now, null, null, 0, 0);
 5     var now = DateTime.Now;
 6     return Search(null, null, now, now);
 7 }
 8 
 9 /// 查詢符合條件的公告
10 /// 釋出者
11 /// 標題
12 /// 開始時間
13 /// 結束時間
14 public static EntityList Search(String poster, String title, DateTime start, DateTime end)
15 {
16     if (Meta.Count ();
17 
18     // 公告的總數一般不多,可以使用實體快取
19     if (Meta.Count  e.Poster.Contains(poster));
25         if (!title.IsNullOrWhiteSpace()) list = list.Where(e => e.Title.Contains(title));
26         if (start > DateTime.MinValue) list = list.Where(e => e.StartTime > start);
27         if (end > DateTime.MinValue) list = list.Where(e => e.EndTime (list);
30     }
31 
32     var exp = new WhereExpression();
33 
34     // 使用條件表示式構建查詢SQL語句
35     if (!poster.IsNullOrWhiteSpace()) exp &= _.Poster.Contains(poster);
36     if (!title.IsNullOrWhiteSpace()) exp &= _.Title.Contains(title);
37     if (start > DateTime.MinValue) exp &= _.StartTime > start;
38     if (end > DateTime.MinValue) exp &= _.EndTime 

 至於_.這種情況,可能有人剛開始看不懂,其實看看XCoder生成的實體型別程式碼就知道了。這個型別是快速訪問欄位用的,非常方便。

3.資料庫的初始化,你難道還在手動或者用? 

  這是一個很隱蔽的功能,應該有很多人剛入門的朋友沒有注意到。這也是一個非常人性化的操作,在生成的“模型”裡面,業務中有一個靜態的建構函式InitData(),看看裡面都有什麼,這裡舉例是隨便找的一個表,生成的結構相同,只不過欄位不一樣而已。雖然上面註釋了,但很明顯,這裡是教大家怎麼用的。在資料庫反向工程執行的時候,首次連線資料庫,就會執行這個方法,如果資料表是空的,那麼程式就會自動執行指定的程式碼,進行資料插入。也就是說在你實際部署的時候,對於系統的初始化資料,根本不用去執行什麼資料庫SQL指令碼,或者手動進行新建資料庫和初始化的工作。

  這一切都可以在程式裡面迅速完成,而且非常簡單,對於開發和測試來說,都非常簡單,不需要你做任何管理。比如一些使用者表和管理員表,可以初始化幾個帳號;例如一些單位的部門資訊,許可權資訊,都可以進行初始化。而且這一切都支援跨資料庫,可以在幾個資料庫之間切換;而不是每一種資料庫準備一套指令碼。試想一下,開發機用而程式只需要改變一個連線字串就可以自動初始化這些資料。

  看看我的一個例子,下面是一個 歐洲賠率公司的 資訊表,系統用到的賠率公司的數量不多,只有20條左右。因為,只要是新的環境,或者實際部署,系統就會根據下面的邏輯進行初始化工作。FastInsert是一個快速插入當前記錄的方法,自己手動寫的。 

 1         /// 首次連線資料庫時初始化資料,僅用於實體類過載,使用者不應該呼叫該方法
 2         [EditorBrowsable(EditorBrowsableState.Never)]
 3         protected override void InitData()
 4         {
 5             base.InitData();
 6             if (Meta.Count > 0) return;
 7             if (XTrace.Debug) XTrace.WriteLine("開始初始化{0}賠率公司資料……", typeof(CompanyInfo).Name);
 8 
 9             #region 資料儲存
10             FastInsert("平均賠率", 1000, true, false, false, true);
11             FastInsert("競彩官方", 999, true, false, false, true);
12             FastInsert("威廉希爾", 252, true, false, false, true);
13             FastInsert("立博", 251, true, true, false, true);
14             FastInsert("bet 365", 469, true, true, false, true);
15             #region 其他公司
16             FastInsert("Interwetten", 122, true, false, false, true);
17             FastInsert("SNAI", 179, true, false, false, true);
18             FastInsert("bwin", 65, true, false, false, true);
19             FastInsert("偉德", 253, true, true, false, true);
20             FastInsert("易勝博", 254, true, true, false, true);
21             FastInsert("澳門", 247, true, true, false, true);
22             FastInsert("Expekt", 92, true, false, false, true);
23             FastInsert("Coral", 77, true, false, false, true);
24             FastInsert("Iceland", 117, true, false, false, true);
25             FastInsert("Oddset", 142, true, false, false, true);
26             FastInsert("皇冠", 300, true, false, false, true);
27             FastInsert("利記sbobet", 169, true, true, false, true);
28             FastInsert("金寶博", 250, true, true, false, true);
29             FastInsert("10BET", 1, true, true, false, true);
30             //2014-05-08 增加亞盤公司,大小盤公司和進球公司
31             FastInsert("明陞", 566, false, true, true, true);
32             #endregion
33             FastInsert("12BET", 116, false, true, false, true);         
34             #endregion
35 
36             if (XTrace.Debug) XTrace.WriteLine("完成初始化{0}賠率公司資料!", typeof(CompanyInfo).Name);
37         }
38 
39         /// 快速插入公司資訊,只在內部初始化的時候用
40         static void FastInsert(String name, Int32 companyId, Boolean isEurop, Boolean isAais, Boolean isTrade = false, 
                                                                                             Boolean isAuthority = false)
41         {
42             var entity = new CompanyInfo();
43             entity.Name = name;
44             entity.OnceName = String.Empty;
45             entity.ComanyID = companyId;
46             entity.IsTrading = isTrade;
47             entity.IsAuthority = isAuthority;
48             entity.IsEurope = isEurop;
49             entity.IsAsia = isAais;
50             entity.Insert();
51         }
52         #endregion

 資料庫的主要操作就十分增刪查改,其中查詢應該是最頻繁的操作,在XCode中用好查詢,不僅僅是會寫查詢,還要靈活運用XCode支援的三級快取。要自己花點功夫去研究原始碼,當然X元件的影片和很多部落格都有講解到,可以去論壇和本文的部落格中去尋找。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2459/viewspace-2800049/,如需轉載,請註明出處,否則將追究法律責任。

相關文章