本博客所有文章分類的總目錄:http://m.survivalescaperooms.com/asxinyu/p/4288836.html
Newlife XCode組件相關文章目錄:http://m.survivalescaperooms.com/asxinyu/p/4329747.html
聲明:此Newlife.XCode非Mac的XCode,避免誤會。
1.QQ群:1600800
2.博客論壇 :NewlifeX論壇(同時也是.Net Micro Framework/ApolloOS的交流論壇,幫助軟件開發者使用C#快速進入嵌入式開發領域) 大石頭博客Asxinyu博客使用XCode已經3年了,談不上精通,都是些基礎功能使用,以前源碼啃過很多次,了解過部分功能的實現細節,但終歸是要應用的,當沒有時間時,了解使用就可以了,所以現在更多關注業務相關的東西,數據庫操作,XCode已經很完善了。本文就對這幾年應用過程的一些問題,以及很多人經常問起來的問題進行一個總結。今天就介紹2個主要的,比較常見的使用:表達式查詢,實體數據初始化。
我們將在下一篇博客中重點介紹更加重量級的分庫分表功能,以及通用配置輔助類的使用。敬請關注。
如果文章或者資源對您有用,請“推薦”和關注,接下來還有很多.NET平臺關于機器學習、彩票分析平臺和預測的文章和資源待發表。
本文原始地址:http://m.survivalescaperooms.com/asxinyu/p/4248281.html
XCode對查詢語法和靈活性是我見過的ORM中最優雅的,最簡單體貼的。XCode由于支持多種數據庫,并且效率很高的原因就是在這些數據庫核心操作的背后有許多精巧的設計,其支持的查詢就是XCode靈活強大的表現之一,每天寫著重復的sql,調試,拼接參數,真的很累,那么看看XCode中的查詢,真的是賞心悅目,是一種享受吧。首先對XCode的查詢語法進行一個簡單的總結和描述:
1)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<TEntity>封裝好的靜態方法,里面包含很多東西,建議熟練使用后的朋友,好好看一看,對理解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 /// <summary> 2 /// 拷貝數據庫,只需要數據庫連接字符串和源數據庫即可 3 /// </summary> 4 /// <param name="originConn">源數據庫連接字符串</param> 5 /// <param name="desConn">目的數據庫連接字符串</param> 6 /// <param name="perCount">每次獲取的記錄數目,如果默認-1則會自動調用函數計算一個合理值</param> 7 public static void CopyDataBase(string originConn,string desConn,int perCount = -1) 8 { 9 //思路:通過源數據庫獲取架構信息,然后反向工程,然后導出數據 10 DAL dal = DAL.Create(originConn);11 List<IDataTable> 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 < 0) perCount = GetDataRowsPerConvert (allCount );24 int pages = (int)Math.Ceiling ((double)((double )allCount/(double )perCount));25 for (int i = 0; i < pages ; i++)26 {27 Factory.ConnName = originConn;28 IEntityList modelList = Factory.FindAll(string.Empty, string.Empty, string.Empty, i * perCount, perCount);29 Factory.ConnName = desConn;30 modelList.Insert(true);31 }32 Console.WriteLine("數據庫{0} 數據轉移完成!",item.Name );33 }34 }6)XCode中的查詢表達式類型是WhereExPRession,實際中的SQL語句拼接的結果就是WhereExpression類型,而該類型的拼接支持&,|運算符的重載,可以直接將不同的條件組合在一起。拼接的字段名稱為XX._.字段名,_的實體類型的用處也主要在這里,注意WhereExpression類型是可以隱式轉換為String類型的。這也是為什么有人不解直接將WhereExpression類型放入FindAll第一個參數的原因,其實已經轉換成String了。看看1個實際查詢綜合的例子(來源于大石頭BBX項目中的代碼):
1 /// <summary>獲取有效的廣告列表</summary> 2 public static EntityList<Announcement> GetAvailableList() 3 { 4 //return FindAll(_.StartTime < DateTime.Now & _.EndTime > DateTime.Now, null, null, 0, 0); 5 var now = DateTime.Now; 6 return Search(null, null, now, now); 7 } 8 9 /// <summary>查詢符合條件的公告</summary>10 /// <param name="poster">發布者</param>11 /// <param name="title">標題</param>12 /// <param name="start">開始時間</param>13 /// <param name="end">結束時間</param>14 public static EntityList<Announcement> Search(String poster, String title, DateTime start, DateTime end)15 {16 if (Meta.Count <= 0) return new EntityList<Announcement>();17 18 // 公告的總數一般不多,可以使用實體緩存19 if (Meta.Count < 1000)20 {21 var list = Meta.Cache.Entities.ToList().AsEnumerable();22 23 // 使用Linq從實體緩存里面過濾需要的數據24 if (!poster.IsNullOrWhiteSpace()) list = list.Where(e => 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 < end);28 29 return new EntityList<Announcement>(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 < end;39 40 return FindAll(exp, null, null, 0, 0);41 } 至于_.這種情況,可能有人剛開始看不懂,其實看看XCoder生成的實體類型代碼就知道了。這個類型是快速訪問字段用的,非常方便。
這是一個很隱蔽的功能,應該有很多人剛入門的朋友沒有注意到。這也是一個非常人性化的操作,在生成的“模型”里面,業務中有一個靜態的構造函數InitData(),看看里面都有什么,這里舉例是隨便找的一個表,生成的結構相同,只不過字段不一樣而已。雖然上面注釋了,但很明顯,這里是教大家怎么用的。在數據庫反向工程執行的時候,首次連接數據庫,就會執行這個方法,如果數據表是空的,那么程序就會自動執行指定的代碼,進行數據插入。也就是說在你實際部署的時候,對于系統的初始化數據,根本不用去執行什么數據庫SQL腳本,或者手動進行新建數據庫和初始化的工作。
這一切都可以在程序里面迅速完成,而且非常簡單,對于開發和測試來說,都非常簡單,不需要你做任何管理。比如一些用戶表和管理員表,可以初始化幾個帳號;例如一些單位的部門信息,權限信息,都可以進行初始化。而且這一切都支持跨數據庫,可以在幾個數據庫之間切換;而不是每一種數據庫準備一套腳本。試想一下,開發機用sqlite開發,實際部署用MySQL,而程序只需要改變一個連接字符串就可以自動初始化這些數據。
看看我的一個例子,下面是一個 歐洲賠率公司的 信息表,系統用到的賠率公司的數量不多,只有20條左右。因為,只要是新的環境,或者實際部署,系統就會根據下面的邏輯進行初始化工作。FastInsert是一個快速插入當前記錄的方法,自己手動寫的。
1 /// <summary>首次連接數據庫時初始化數據,僅用于實體類重載,用戶不應該調用該方法</summary> 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}賠率公司數據&hell
新聞熱點
疑難解答