你還可以參考本博客其他的XCode以及.NET開源項目的相關文章:
Newlife XCode組件資源目錄匯總【2013年版】擁有自己的代碼生成器—Newlife.Xcode模板編寫教程
【原創】開源.NET下的XML數據庫介紹及入門 Newlife.XCode對象容器與接口操作實例
【轉載總結】關於泛型基類的相關知識 利用Xcode 20行代碼搞定任何數據庫的遷移
使用Xcode自動向數據庫插入測試數據(不需要實體類) 關於Xcode數據庫反向工程的理解
【原創分享】Matlab.NET混編調用Figure窗體 【原創】Matlab與.NET基於類型安全的接口編程入門
【原創】C#開源輕量級對象數據庫NDatabase介紹 【原創】開源Word讀寫組件DocX介紹與入門
【原創】.NET開源壓縮組件介紹與入門 【開源原創】.NET開源表達式計算組件介紹與使用
聲明:此Newlife.XCode非Mac的XCode,避免誤會。
1.QQ群:1600800
2.博客論壇 : NewlifeX論壇 (同時也是.Net Micro Framework/ApolloOS的交流論壇,幫助軟件開發者使用C#快速進入嵌入式開發領域) 大石頭博客 Asxinyu博客使用XCode已經3年了,談不上精通,都是些基礎功能使用,以前源碼啃過很多次,了解過部分功能的實現細節,但終歸是要應用的,當沒有時間時,了解使用就可以了,所以現在更多關注業務相關的東西,數據庫操作,XCode已經很完善了。本文就對這幾年應用過程的一些問題,以及很多人經常問起來的問題進行一個總結。今天就介紹2個主要的,比較常見的使用:表達式查詢,實體數據初始化。
我們將在下一篇博客中重點介紹更加重量級的分庫分表功能,以及通用配置輔助類的使用。敬請關注。
如果文章或者資源對您有用,請“推薦”和關注,接下來還有很多.NET平台關於機器學習、彩票分析平台和預測的文章和資源待發表。
本文原始地址:http://www.cnblogs.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}賠率公司數據……", 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 /// <summary>快速插入公司信息,只在內部初始化的時候用</summary> 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組件的視頻和很多博客都有講解到,可以去論壇和本文的博客中去尋找。
鏈接: http://pan.baidu.com/s/1nt1bLDB 密碼: aqx5,下載源碼別忘記推薦哦。。。。