我的KT库之----数据对象
了解或者認(rèn)識(shí)KT:
http://www.cnblogs.com/kingthy/archive/2011/08/08/2130973.html
在項(xiàng)目中如何使用KT?
KT是一個(gè)庫,所以將KT的dll文件引用到您的項(xiàng)目上即可使用KT里的函數(shù)功能。
本節(jié)將介紹大家認(rèn)識(shí)KT庫里的數(shù)據(jù)對(duì)象(DbObject)。KT里的數(shù)據(jù)對(duì)象是KT簡易ORM框架里的一個(gè)對(duì)象角色,它存放于在“KT.Framework“下,當(dāng)你已在你的項(xiàng)目里引用了KT庫后,則寫下以下代碼就可以使用數(shù)據(jù)對(duì)象了。
using KT.Framework;
什么是數(shù)據(jù)對(duì)象
數(shù)據(jù)對(duì)象可用于簡單處理數(shù)據(jù)的存儲(chǔ)與交互,如將數(shù)據(jù)進(jìn)行實(shí)體化處理。KT里的數(shù)據(jù)對(duì)象DbObject對(duì)象類似于一個(gè)“字典”對(duì)象,添加到數(shù)據(jù)對(duì)象里的數(shù)據(jù)都被放入內(nèi)部的一個(gè)“槽”里進(jìn)行維護(hù),如以下的代碼:
DbObject obj = new DbObject(); obj["name"] = "張三"; obj["age"] = 23; Console.WriteLine("姓名:{0}", obj["name"]); Console.WriteLine("年齡:{0}", obj["age"]);//或者通過SetData/GetData<T>方法設(shè)置/獲取數(shù)據(jù) obj.SetData("name", "李四"); Console.WriteLine("姓名:{0}", obj.GetData<string>("name")); Console.WriteLine("年齡:{0}", obj.GetData<int>("age")); Console.Read();?
擴(kuò)展數(shù)據(jù)對(duì)象
雖可以直接將數(shù)據(jù)對(duì)象當(dāng)作一個(gè)字典對(duì)象使用,但很多場合下我們卻是需要將數(shù)據(jù)進(jìn)行實(shí)體化處理,所以我們需要將數(shù)據(jù)對(duì)象進(jìn)行擴(kuò)展。如以下的代碼示例:
/// <summary> /// 用戶對(duì)象 /// </summary> public class DbUser : DbObject {public User(){}/// <summary>/// 姓名/// </summary>public string Name{get{return this.GetData<string>("Name", null);}set{this["Name"] = value;}}/// <summary>/// 年齡/// </summary>public int Age{get{return this.GetData<int>("Age", 0);}set{this["Age"] = value;}} }?
這樣擴(kuò)展后,我們的數(shù)據(jù)對(duì)象User就是強(qiáng)類型的了,如下面的使用代碼示例:
DbUser user = new DbUser(); user.Name = "張三"; user.Age = 12;?
有時(shí)我們的類里需要使用到類內(nèi)部的“字段”,則我們也可以將“字段”關(guān)聯(lián)到數(shù)據(jù)對(duì)象里,如下面的擴(kuò)展方法處理
/// <summary> /// 用戶對(duì)象 /// </summary> public class DbUser : DbObject {public DbUser(){this.AddInternalData("Id", () => this.Id, (o) => this.Id = o.As<int>());}/// <summary>/// 編號(hào)/// </summary>public int Id;/// <summary>/// 姓名/// </summary>public string Name{get{return this.GetData<string>("Name", null);}set{this["Name"] = value;}}/// <summary>/// 年齡/// </summary>public int Age{get{return this.GetData<int>("Age", 0);}set{this["Age"] = value;}} }我們通過“AddInternalData”方法,將Id字段加入到了數(shù)據(jù)對(duì)象里,這樣我們就可以在數(shù)據(jù)對(duì)象里使用”Id”數(shù)據(jù)了,如下面代碼
DbUser user = new DbUser();user["Id"] = 33;Console.WriteLine(user.Id); //輸出33user.Id = 22;Console.WriteLine(user.GetData<int>("Id")); //輸出22?
?
還有一種情況,有時(shí)對(duì)一種數(shù)據(jù),我們多有種不同的名稱,比如“用戶名”,有時(shí)使用為“name“,有時(shí)又為“username“,比如以下兩句SQL語句
?
SELECT Name FROM [User] SELECT B.BookName,U.UserId,U.Name AS UserName FROM [Book] B INNER JOIN [User] U ON U.Id=B.UserId在第一句SQL語句里,因?yàn)橹粏渭儾樵冇脩舯?#xff0c;所以可以使用“name”做用戶的名稱,但在第二句SQL語句里,為了區(qū)別用戶的數(shù)據(jù),又采用了"username”做為用戶名數(shù)據(jù),對(duì)于這種情況,我們也可以在數(shù)據(jù)對(duì)象里進(jìn)行擴(kuò)展,如以下示例代碼
/// <summary> /// 用戶對(duì)象 /// </summary> public class DbUser : DbObject {public DbUser(){this.AddInternalData("Id", () => this.Id, (o) => this.Id = o.As<int>());}/// <summary>/// 編號(hào)/// </summary>public int Id;/// <summary>/// 姓名/// </summary>public string Name{get{return this.GetData<string>("Name", null);}set{this["Name"] = value;}}/// <summary>/// 年齡/// </summary>public int Age{get{return this.GetData<int>("Age", 0);}set{this["Age"] = value;}}protected override bool OnBeforeSetData(string name, object value){if ("username".Equals(name, StringComparison.OrdinalIgnoreCase)){//調(diào)用內(nèi)部的SetDataImp方法,可避免再一次觸發(fā)OnBeforeSetData方法this.SetDataImp("name", value);/*** 注:以下兩種方式都會(huì)再一次觸發(fā)OnBeforeSetData方法,所以盡量不要使用* this.SetData("name", value);* this.Name = value.As<string>();**/return false;}return base.OnBeforeSetData(name, value);} }?
使用示例
DbUser user = new DbUser();user.Name = "張三";Console.WriteLine(user.Name); //輸出"張三"user["username"] = "李四";Console.WriteLine(user.Name); //輸出"李四"?
?
?
數(shù)據(jù)對(duì)象的使用
在上面示例代碼里,也許會(huì)有很多同學(xué)都會(huì)問“這樣的數(shù)據(jù)對(duì)象,看不出它的好處在哪里,并且比直接寫一個(gè)類結(jié)構(gòu)還更復(fù)雜”,是的,直接這樣使用數(shù)據(jù)對(duì)象,真的體現(xiàn)不出它的好處在哪里,但如果將數(shù)據(jù)對(duì)象與“數(shù)據(jù)庫”掛上關(guān)系,那就可以體現(xiàn)數(shù)據(jù)對(duì)象的好處在哪里了。比如我們的數(shù)據(jù)庫有這樣的兩個(gè)表
表1:User 用戶表
| Id | int |
| Name | nvarchar(20) |
| Age | int |
| Phone | nvarchar(20) |
| LocationId | int |
表2:Location 位置表
| Id | int |
| UserId | int |
| City | nvarchar(30) |
| Address | nvarchar(200) |
| Zipcode | nvarchar(6) |
?
現(xiàn)在我們需要獲取User表里的數(shù)據(jù),比如有以下的SQL語句
SELECT * FROM [User]根據(jù)上表可以知道,這樣的查詢語句,將獲取到的數(shù)據(jù)共有5個(gè)(Id,Name,Age,Phone,LocationId),但如果將這些數(shù)據(jù)映射到某個(gè)實(shí)體類去,并且實(shí)現(xiàn)數(shù)據(jù)的一一對(duì)應(yīng),那我們就需要定義這5個(gè)屬性或字段,如下面的類
/// <summary> /// 用戶對(duì)象 /// </summary> public class User {public User(){}public int Id { get; set; }public string Name { get; set; }public int Age { get; set; }public string Phone { get; set; }public int LocationId { get; set; } }?
但假如我們現(xiàn)在在獲取用戶數(shù)據(jù)時(shí)還需要同時(shí)獲取用戶的地址位置數(shù)據(jù),如以下的SQL語句
SELECT U.Id,U.Name,L.City,L.Address,L.Zipcode FROM [User] U INNER JOIN [Location] L ON L.Id=U.Location.Id?
這條查詢語句我們共需要獲取Id,Name,City,Address,Zipcode這5個(gè)數(shù)據(jù),很明顯,這里的數(shù)據(jù)與上面的User類結(jié)構(gòu)是不相同的,也就是如果需要將這條SQL語句映射為類對(duì)象,我們又需要建多一個(gè)類結(jié)構(gòu)對(duì)象。也就是每當(dāng)我們SQL語句有變化時(shí),我們就需要增加不同的類對(duì)象,這樣對(duì)我們來說是非常麻煩且工作量是非常之大的。
?
如果我們使用數(shù)據(jù)對(duì)象來做數(shù)據(jù)映射,因?yàn)閿?shù)據(jù)對(duì)象本來就是一個(gè)“字典”對(duì)象,所以不管我們的SQL語句如何變化,數(shù)據(jù)都是進(jìn)入到數(shù)據(jù)對(duì)象里的“槽”里,再根據(jù)“擴(kuò)展數(shù)據(jù)對(duì)象”反映到對(duì)象的“屬性”或“字段”里。比如上面兩句SQL語句我們都可以將其映射為“擴(kuò)展數(shù)據(jù)對(duì)象”那段里定義的“DbUser”對(duì)象,對(duì)于未“擴(kuò)展”的“Phone,LocationId,City,Address,Zipcode“等數(shù)據(jù),我們則可以在需要時(shí)通過數(shù)據(jù)對(duì)象的“GetData<T>”方法獲取,如下:
var phone = user.GetData<string>("Phone"); var locationId = user.GetData<int>("LocationId");?
從上面的示例中,我們可以看到DbObject有點(diǎn)類似于DataTable,確切的說應(yīng)該是像DataRow,只當(dāng)一個(gè)相同的DbObject列表集時(shí),才能說象DataTable。KT也提供了DbObject的擴(kuò)展方法,通過擴(kuò)展方法DataTable與List<DbObject>可以互相轉(zhuǎn)換。如下示例:
DataTable table = new DataTable();table.Columns.Add("name", typeof(string));table.Columns.Add("age", typeof(int));table.Rows.Add("張三", 20);table.Rows.Add("李四", 30);var users = table.ToDbObjectList<DbUser>();Console.WriteLine(users.Count); //輸出:2Console.WriteLine(users[0].Name); //輸出:張三var userTable = users.ToDataTable();Console.WriteLine(userTable.Rows.Count); //輸出:2Console.WriteLine(userTable.Rows[0]["Name"]);//輸出:張三總結(jié)
以上是生活随笔為你收集整理的我的KT库之----数据对象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 归并排序 java_Java实现归并排序
- 下一篇: ant 执行多个构建文件