詳解ORM組件XCode教程 圖文并茂
ORM組件XCode教程是本文要介紹的內容,本篇才真正是XCode教程***篇?!端儆[》是為了以最簡潔的語言最短小的篇幅去吸引開發者;《簡介》則是對XCode組件和XCode開發模式的一個整體介紹,讓開發者從宏觀的角度去理解XCode;《共舞》把XCode提到了一個新的高度,讓開發者感受到它的貴族血統!
先拋出三篇來吸引人,再出《動手》,其實就是吊人胃口。如果到這里你還沒有想試一試XCode的念頭沖動,好吧,我承認是我的失敗,不過你可以欺騙我,可別欺騙你自己!
XCode開發模式建議先有數據庫再有實體模型,然后借助代碼生成器生成實體代碼;當然你要反過來先做實體模型也是可以的,XCode之下的實體,支持反向生成數據庫結構。
下面以《速覽》中的UserMember為例,建立數據表:
數據表名: 用戶 (UserMember)
數據庫命名規范:
(1)名稱必須使用通俗易懂的英文單詞全拼,常用的縮略詞(如ID)除外
(2)使用駝峰命名規則,每個單詞首字母大寫,其它小寫
(3)名稱必須簡潔明了,不要加多余的前綴(如表名前加tbl),字段名也不要加表名前綴
(4)不得使用SQL關鍵字或C#關鍵字作為表名或字段名
(5)布爾型字段名稱必須是IsAbb的形式
(6)字符串類型統一使用nvarchar,大文本使用ntext,除非特殊情況,否則不用其它文本類型
(7)建議給每張表建立一個自增的ID字段并作為主鍵,以利于數據分頁管理
(8)建議給每張表和每個字段加上說明
(9)使用代碼生成器生成代碼(先看代碼,待會講過程):
代碼
- /// <summary>
- /// 用戶
- /// </summary>
- [Serializable]
- [DataObject]
- [Description("用戶")]
- [BindTable("UserMember", Description = "用戶", ConnName = "Test")]
- public partial class UserMember
- {
- #region 屬性
- private Int32 _ID;
- /// <summary>
- /// 編號
- /// </summary>
- [Description("編號")]
- [DataObjectField(true, true, false, 10)]
- [BindColumn("ID", Description = "編號", DefaultValue = "", Order = 1)]
- public Int32 ID
- {
- get { return _ID; }
- set { if (OnPropertyChange("ID", value)) _ID = value; }
- }
- private String _Account;
- /// <summary>
- /// 賬號
- /// </summary>
- [Description("賬號")]
- [DataObjectField(false, false, true, 50)]
- [BindColumn("Account", Description = "賬號", DefaultValue = "", Order = 2)]
- public String Account
- {
- get { return _Account; }
- set { if (OnPropertyChange("Account", value)) _Account = value; }
- }
- private String _DisplayName;
- /// <summary>
- /// 顯示名
- /// </summary>
- [Description("顯示名")]
- [DataObjectField(false, false, true, 50)]
- [BindColumn("DisplayName", Description = "顯示名", DefaultValue = "", Order = 3)]
- public String DisplayName
- {
- get { return _DisplayName; }
- set { if (OnPropertyChange("DisplayName", value)) _DisplayName = value; }
- }
- #endregion
- #region 獲取/設置 字段值
- /// <summary>
- /// 獲取/設置 字段值。
- /// 一個索引,基類使用反射實現。
- /// 派生實體類可重寫該索引,以避免反射帶來的性能損耗
- /// </summary>
- /// <param name="name">字段名</param>
- /// <returns></returns>
- public override Object this[String name]
- {
- get
- {
- switch (name)
- {
- case "ID": return ID;
- case "Account": return Account;
- case "DisplayName": return DisplayName;
- default: return base[name];
- }
- }
- set
- {
- switch (name)
- {
- case "ID": _ID = Convert.ToInt32(value); break;
- case "Account": _Account = Convert.ToString(value); break;
- case "DisplayName": _DisplayName = Convert.ToString(value); break;
- default: base[name] = value; break;
- }
- }
- }
- #endregion
- #region 字段名
- /// <summary>
- /// 取得字段名的快捷方式
- /// </summary>
- public class _
- {
- /// <summary>
- /// 編號
- /// </summary>
- public const String ID = "ID";
- /// <summary>
- /// 賬號
- /// </summary>
- public const String Account = "Account";
- /// <summary>
- /// 顯示名
- /// </summary>
- public const String DisplayName = "DisplayName";
- }
- #endregion
- }
代碼不多,分為屬性、索引器和嵌套類三大塊,其中后兩塊還不是必須的,所以即使是手工編碼也不會太麻煩。
所使用的代碼生成器XCoder,是一個基于XCode的模版標簽替換生成器。XCode提供數據庫結構信息,用戶設計模版,XCoder根據模版標簽進行替換。上面的代碼還有數據字典表格,都是XCoder生成的,只是所使用的模版不同而已。有興趣的朋友完全可以定制自己的代碼生成器,DAL類的Tables屬性可以取得該連接的表架構信息,如DAL.Create("Test").Tables可以取得連接名為Test的數據庫的架構信息。
#p#
XCoder的使用很簡單,打開配置文件XCoder.exe.config,增加一個連接字符串
代碼
- <?xml version="1.0" encoding="utf-8" ?>
- <configuration>
- <connectionStrings>
- <add name="Test" connectionString="Data Source=.;Initial Catalog=Test;Integrated Security=True;" providerName="System.Data.SqlClient"/>
- </connectionStrings>
- </configuration>
運行XCoder.exe,可以在連接下拉框選擇連接字符串
點擊連接,列出該庫所有表和視圖
設置命名空間、輸出目錄和連接名等信息,選擇“數據”模版,點擊生成
因為XCode是充血模型,使用的時候是不需要指定數據庫連接的,所以實體類里面默認指定連接名。
#p#
XCode模型追求簡單實用,所以沒有區分數據層和業務層。但是XCode實體類有數據類和業務類的說法,剛才上面的“數據”模版生成的就是數據類,下面生成業務類
可以看出,數據類和業務類其實就是同一類,只不過使用了分部類partial,把一個類分拆到兩個文件里面去。數據類記錄表結構信息,基本上依靠于生成;業務類***次生成后只有一些注釋,用于引導開發者如何實現自己想要的功能。業務代碼等人工編寫的代碼,都要求卸載業務類里面,當表結構改變需要重新生成代碼時,僅生成數據類即可,人工編寫的代碼保留在業務類中,不至于被覆蓋。
XCoder在輸出目錄生成了代碼文件,復制到vs里面去
再看看例子代碼
代碼
- //新增數據,Save等效于Insert
- UserMember user = new UserMember();
- user.Account = "asdf";
- user.Save();
- //user.Insert();
- //ID作為自增字段,保存后自動設為新值
- Console.WriteLine(user.ID);
- //查找數據,等效
- user = UserMember.Find("Account", "asdf");
- user = UserMember.Find(UserMember._.Account, "asdf");
- user = UserMember.FindByAccount("asdf");
- user.DisplayName = "測試數據";
- //讀取成員數據,等效
- String str = (String)user["DisplayName"];
- str = user.DisplayName;
- //給成員賦值,等效
- user.DisplayName = "測試數據";
- user["DisplayName"] = "測試數據";
- //保存數據,等效
- user.Save();
- //user.Update();
- Console.WriteLine(user.ID);
- user.Delete();
編譯,提示user = UserMember.FindByAccount("asdf")這句報錯,沒有FindByAccout方法。忘了這是我手工寫的了
- public static UserMember FindByAccount(String account)
- {
- return Find(_.Account, account);
- }
這個方法是根據賬號查找用戶。一般建議,FindByXxxx表示根據某個條件查詢一個對象,FindAllByXxxx表示查詢符合某個條件的所有對象的集合。
再次編譯,通過。運行
又忘了,我們還沒有設置連接字符串呢。增加連接字符串
- <add name="Test" connectionString="Data Source=.;Initial Catalog=Test;Integrated Security=True;" providerName="System.Data.SqlClient" />
這里要求連接名必須是Test,因為生成數據類的時候,指定了連接名為Test,所以才有剛才的異常,提示設置Test連接字符串。后面就是標準的連接字符串了,當然,這個時候是可以修改為Access、Oracle、MySql等連接字符串的,盡管我們開始的時候是在SqlServer中建立表結構。因為實體類已經建立完成,它與具體數據庫無關,只有在運行時探測是哪一種數據庫,再根據情況生成相應的查詢/操作SQL。
XCode除了能獲取數據庫架構信息外,還能設置數據庫架構,也就是能夠根據實體類自動進行建表或者修改表結構。所以,不用擔心修改連接字符串指向別的數據庫后,會因為沒有數據表而報錯。這個小功能有個好處,比如生產環境是Oracle數據庫,而開發環境比較差,跑不起Oracle,完全可以在開發環境用Access進行設計,部署到生成環境再修改連接字符串,XCode會盡其所能的屏蔽數據庫操作差異。
打開XCode的OrmDebug開關(用于輸出SQL語句),再次運行
跟上面的代碼進行比對,可以加深理解。OrmDebug開關對于學習XCode和解決問題非常有用。
上面是控制臺的例子,下面看看Web的例子。
#p#
在生成實體類代碼的時候,可以看到還有兩個模版“列表頁”和“表單”,取消“中文文件名”選擇,分別生成這兩個模版的代碼。新建一個網站,把它們復制進去
設置連接字符串,預覽UserMember.aspx
回到剛才的控制臺代碼,我們另外寫一段插入測試數據的代碼
- for (int i = 0; i < 176; i++)
- {
- UserMember user = new UserMember();
- user.Account = "User" + i;
- user.DisplayName = "用戶" + i;
- user.Insert();
- }
這段代碼將會向數據庫插入176行數據。刷新UserMember.aspx頁面
列表顯示、分頁、排序、編輯、刪除等功能都有了。
我們對這個頁面做一點修改,添加一個到UserMemberForm.aspx的鏈接,并且把GridView里面的賬號列改為超鏈接,也鏈接到UserMemberForm.aspx,并且帶上ID作為參數。
點擊“添加用戶”
添加一個用戶
點擊賬號aaa,進入表單編輯頁面,注意地址欄的ID=179
又一次,我們沒有編寫代碼!
其實這些都是一些非常簡單的功能,列表頁就是GridView+ObjectDataSource +實體類,表單頁就是FormView+ObjectDataSource+實體類,沒有傳遞ID的時候為添加狀態。
Web的例子就到這里,詳細的用法可以回過頭看看《與ObjectDataSource共舞》,里面提到的批量生產正是本篇所使用的代碼生成器生成列表頁和表單頁。