DataSet相信大家都很熟悉了,但是什么是類型化的DataSet?在ASP.NET三層的WEB應用程序中經常可以看到實體類,實體類的出現讓人們可以在開發中有更加友好的訪問數據的方法,一個實體類中其實就是封裝了某個數據表的所有字段,把這個數據表作為一個對象來控制它的所有屬性。類型化DataSet在開發中的作用就好象實體類,它的功能也和實體類相仿,我們可以把一張數據表作為一個封裝好的實體類來使用。說到這里大家可能想起來一個詞“強類型”,對!我今天介紹的類型化DataSet其實就是有的人所說的“強類型DataSet”,這里我不用這個“強類型”來修飾這樣的DataSet,因為“強”類型的Dataset其實也有它的弱點,這些弱點我會在下面的介紹中一一道出,所以它不是真正的“強”,這里就叫它“類型化”的准確一些吧。
類型化DataSet是從DataSet派生的,當然,同時派生出來的類不只有類型化DataSet,也有派生於DataTable的類型化DataTable、派生於DataRow的類型化DataRow等等。而這些派生出來的類都定義了多個附加的屬性和方法,為基礎類提供了安全而方便友好的訪問,並且可以提高設計效率和運行效率。
類型化DataSet簡化了編程,同時不容易出現錯誤,想象一下,普通DataSet中,只能通過列名索引訪問一個列的值,如果把索引名字寫錯,這個時候編譯器是不會發現錯誤的,但是對於類型化DataSet就不會了,如果索引寫錯編程人員馬上就可以知道,因為類型化DataSet的列是被當作對象的屬性來訪問的。
還有就是如果你在你的類型化DataSet中包含多數據集,同時在生成的XSD文件中對這些數據集建立關系和約束,那么,類型化的DataSet會自動生成一些方法來反應這些關系和約束,但是使用普通的DataSet的時候這些你都需要自己做。
關於有人說VS內置的類型化DataSet性能方面不盡如人意,我覺得,類型化DataSet在創建實例對象的時候要比非類型化DataSet多一些開銷(在時間和內存空間上),但是類型化DataSet在填充數據的時候要比非類型化DataSet快,這是因為.NET的DataAdapter在填充數據之前就已經知道應該怎么去Fill一個類型化的DataSet,相比之下,非類型化DataSet就要訪問兩次讀取數據,第一次訪問取得數據表的數據結構信息,第二次訪問的時候才真正的Fill數據。
說道這里,大家一定認為類型化DataSet這還不是“強”?被稱作“強類型DataSet”一點也不為過吧?是的,現在看來類型化DataSet的確是夠“強”,我第一次接觸這樣的DataSet的時候也接觸的是“強類型”的,但是,類型化DataSet有一個它致命的弱點,就是不如非類型化的DataSet靈活,因為類型化DataSet一旦建立,那么它的數據表的結構也就固定了,沒有辦法更改,如果需要修改的話,就必須從新生成!試想一下,如果在開發中需要對其修改,比如添加或者去除字段的話,就會非常非常麻煩,而非類型化DataSet可以根據自己的需要隨時修改,所以,在這里,說類型化DataSet“強”也是片面的。
說了這么多,來看看具體在VS中這么使用類型化的DataSet吧!
添加新項-從彈出窗口中選擇數據-選擇數據集,然后起一個名字,點確定。現在就可以看到設計視圖了。
下一步要做的就是打開服務器資源管理器,然后找到要創建到數據集里的數據表,把它拖到設計視圖中,然后保存,一個類型化DataSet就建立完成了。
(關於例子:在這片文章中我所使用的例子都以這樣的數據表表來舉例:)
1 create table T_Users(Id int primary key identity(1,1) not null,Name nvarchar(20) not null,Age int not null,Tel nvarchar(20) not null)
類型化DataSet的使用以及特點:
首先,類型化DataSet簡化了設計(編程)過程,這也是我喜歡類型化DataSet的主要原因,在普通DataSet的應用中,如果想要訪問一個數據表中的某行的某一個字段的值,我們需要這樣做:
比如讀出T_Users的第一個用戶Name信息:
1 string connStr="Data Source=.\\sqlexpress;Initial Catalog=test;Integrated Security=True"; 2 SqlConnection conn = new SqlConnection(connStr); 3 conn.Open(); 4 SqlCommand cmd = conn.CreateCommand(); 5 cmd.CommandText = "select Name from T_Users"; 6 DataSet ds = new DataSet(); 7 SqlDataAdapter adapter = new SqlDataAdapter(cmd); 8 adapter.Fill(ds); 9 DataTable dt = ds.Tables[0]; 10 string name = dt.Rows[0]["Name"].ToString(); 11 return name;
如果是類型化DataSet我們只需要這么做,(注意這里先要using bbb.DataSetT_UsersTableAdapters;):
T_UsersTableAdapter adapter = new T_UsersTableAdapter(); bbb.DataSetT_Users.T_UsersDataTable users = adapter.GetData(); bbb.DataSetT_Users.T_UsersRow user = users[0]; string Name = user.Name; return Name;
看到了吧?這里的表的關鍵字索引都有友好的自動提示。
這里的T_UsersTableAdapter也就是非類型化DataSet的SqlDataAdapter,T_UsersDataTable也就是非類型化DataSet的DataTable,T_UsersRow也就是非類型化DataSet的DataRow,是不是很好用?只要一“點”就能把表里的關鍵字索引像一個類的屬性一樣“點”出來,這樣大幅度的簡化了開發過程,而且以后的編碼人員在二次開發的時候,也不需要牢記每一個關鍵字索引到底是什么,因為這里有我們要的所有了。而且省略了之前的SqlConnection,SqlCommand等等的操作,因為VS已經自動為什么生成了,這里可能有人會問,那個adapter.GetData();是什么?這個是VS為我們生成的一個訪問數據表方法,這個GetData()方法也是默認建立類型化DataSet的時候自動生成的,它的CommandText 也就是"select * from T_Users";到這里大家可能會說了,一個"select * from T_Users"怎么能夠用呢?是啊,在下面的說明中,我會說道怎么自己給類型化的DataSet添加其他方法,我們就根據對數據的“增,刪,改,查”簡單操作做出相應的方法吧,以后在使用中就要自己根據不同的需要建立了。
例子二:利用類型化DataSet增加一個用戶,用戶Name為Pangzi,Age為22,電話號碼為123:
第一步,雙擊打開剛剛建立的DataSetT_Users,為它添加一個關於Insert的查詢。名字就叫做“InsertNewUser”吧,如圖:
這樣我們的“InsertNewUser”就建立好了,使用如下:
1 T_UsersTableAdapter adapter = new T_UsersTableAdapter(); 2 adapter.InsertNewUser("Pangzi", 22, "123");
簡單吧?是不是有點已經不想用原來的非類型化DataSet了呢?
例子三:利用類型化DataSet刪除剛剛加入的用戶,建立方法為“DeleteUserByName”:
建立方法前幾個步驟一樣,就是sql語句的時候相應的改動,如下圖:
使用:
1 T_UsersTableAdapter adapter =new T_UsersTableAdapter(); 2 adapter.DeleteUserByName("Pangzi");
例子四:利用類型化DataSet修改用戶名為Hexu的Tel為000000,名字為“UpdateTelByName”還是先建立查詢,前幾步驟還是一樣,sql改一下,如圖:
使用如下,還是可以得到友好的自動幫助,這里就不多少了:
1 T_UsersTableAdapter adapter =new T_UsersTableAdapter(); 2 adapter.UpdateTelByName("000000", "Hexu");
還有就是注意在使用的時候,如果在讀出數據后,修改字段值,需要運行adapter.Update();方法,為什么呢?以為類型化DataSet也和非類型化DataSet一樣,是將數據先放在了內存中,如果只做賦值操作的話,修改的內容只是保存在內存中,而沒有updata到這真的數據庫中。這里的adapter.Update();也就和非類型化DataSet的ExecuteNonQuery();是一樣的。
例子:
T_UsersTableAdapter adapter =new T_UsersTableAdapter(); var users = adapter.GetData(); var user = users[0]; user.Name = "HHexu"; adapter.Update(users);
相比之下,類型化DataSet和非類型化DataSet的優、缺點:
1、非類型化DataSet只能通過列名引用,就像例子一一樣,如果寫錯了列名編譯時不會發現錯誤,因此開發時必須要記着列名。
2、int age=Convert.ToInt32(dataset.Rows[0]["Age"]),取到的字段的值是object類型,必須小心翼翼的進行類型轉換,不僅麻煩,而且容易出錯。
3、將非類型化DataSet傳遞給其他使用者,使用者很難識別出有哪些列可以供使用。
4、非類型化DataSet運行時才能知道所有列名,數據綁定麻煩,無法使用Winform、ASP.Net的快速開發功能。而類型化DataSet訪問不但更易於讀取,而且完全受 Visual Studio“代碼編輯器”中 IntelliSense 的支持。
5、就是非類型化DataSet致命缺點,無法更新表的結構。
最后的總結,關於類型化DataSet的使用技術重點還有很多,這里筆者只是介紹了入門的方法,在以后的項目中還是多自己動腦利用類型化DataSet讓開發變得更快速、更簡單。