作為開發(fā)人員,當(dāng)我們在學(xué)習(xí)新技術(shù)時,例子可能是我們最大的敵人。而教程往往設(shè)計得易于理解,但是同時,它們常常加固了懶惰,低效性,甚至于危險的編碼習(xí)慣。再也沒有比ADO.NET示例更能說明問題的了。在本文中,我們將準(zhǔn)備分析一下強類型對象對于你的數(shù)據(jù)庫開發(fā)的意義以及為什么在沒有例子的情況下你應(yīng)該在應(yīng)用程序中盡量使用強類型對象。
具體地說,我們將分析怎樣在Visual Studio 2005中創(chuàng)建和使用強類型DataSet。正如本文所探討的,相對于其它可選的弱類型化的數(shù)據(jù)存取技術(shù),強類型DataSet提供了很多優(yōu)點;并且,借助于Visual Studio 2005,創(chuàng)建和使用強類型DataSet比以往更為容易。
二、 強類型對象基礎(chǔ)及優(yōu)點
為了理解強類型化的含義,不妨讓我們先考慮一下約會的例子。如果你是一個單身漢,那么,你盼望與什么類型的人約會呢?你可能已經(jīng)有了自己具體的標(biāo)準(zhǔn),如富裕且吸引人或可能是居住條件優(yōu)越而性感。無論你的條件如何,當(dāng)你決定想與誰在一起呆更長的時間時,你都難免有一套自己的約會標(biāo)準(zhǔn)。如果你很明智,可以列出一個經(jīng)過事先深思熟慮的列表,這樣可以幫助你節(jié)約不必要的感情付出。把一項"非酗酒"的條件加入到你的約會標(biāo)準(zhǔn)中將會節(jié)約你大量的時間,并且允許你把你的時間和精力用于與更好的候選者約會。
你可能疑惑,這怎么能與編程進(jìn)行比較呢?請聽我的解釋。ADO.NET數(shù)據(jù)存取對象的設(shè)計是為了實現(xiàn)最大的靈活性。除非你遇到相當(dāng)大的麻煩,否則,當(dāng)你從
上面的DataRow就是非類型化的;結(jié)果,你必須以一個串形式作為你要查詢的列名來存取這個值(或者,使用這個列集合中的列的索引值)。很可能,這個列真正存在。一個DataRow列的數(shù)據(jù)類型是對象;我們假定FirstName列的基本數(shù)據(jù)類型是字符串,但是,我們必須顯式地把它轉(zhuǎn)化成一個字符串以便使用它。如果列名發(fā)生變化(例如,你把它改為PersonFirstName),那么編譯器是不能通知你的。千萬不要這樣!因此,如果你的代碼看起來更象如下形式,那么你的生活就會更容易些而你的代碼將更為可靠:
在第二個例子中,我們擁有一個強類型行,并且我們知道FirstName屬性是字符串類型。在此,不會出現(xiàn)雜亂的列名,而且也不存在雜亂的對象轉(zhuǎn)換問題。編譯器為我們作類型檢查,并且我們可以繼續(xù)進(jìn)行其它任務(wù)而不必?fù)?dān)心是否我們已經(jīng)正確輸入了列名。
對于所有其它列也是如此;總之,當(dāng)你能夠使用一個更為具體的類型時,你永遠(yuǎn)不應(yīng)該使用一個泛型對象。但是,請等一下。該強類型對象出自何處?我想我能夠告訴你這些對象是為你自動創(chuàng)建的。然而,正如要建立良好的關(guān)系需要時間和精力一樣,強類型化你的對象也需要付出其它努力。好的方面在于,這里所花費的額外時間是值得的,而且節(jié)省了將來更多的花在調(diào)試上的時間。
存在若干種可以實現(xiàn)強類型化的方法,在本文余下的部分中,我們將討論怎樣在Visual Studio 2005中創(chuàng)建強類型DataSet;當(dāng)然,還將分析一下這樣做的優(yōu)點和缺點。
三、 在VS 2005中創(chuàng)建強類型DataSet
其實,強類型DataSet是一些提前定義了它們自己的列與表的泛型DataSet,這樣編譯器已經(jīng)知道它們將會包含什么內(nèi)容。不是把你的數(shù)據(jù)包裝為一個"露指手套",一個強類型DataSet恰似一個"手套"。每一個Visual Studio的后續(xù)版本會使得強類型化一個DataSet的過程更為容易。在這個示例中,我們將使用來自于SQL Server 2005中的AdventureWorks數(shù)據(jù)庫。這只要簡單地執(zhí)行如下步驟:
1. 打開Visual Studio,然后創(chuàng)建一個新的ASP.NET網(wǎng)站。
2. 在Solution Explorer中,占擊以添加一個新項并且選擇DataSet,并命名為AdventureWorks.xsd。Visual Studio推薦把這個DataSet文件放到App_Code文件夾下。
3. 這個AdventureWorks.xsd將在設(shè)計模式下打開,并且激活"TableAdapter Configuration"向?qū)А,F(xiàn)在,僅僅點擊一下"Cancel"即可。
4. 定位到Server Explorer工具箱,導(dǎo)航到你的SQL Server 2005數(shù)據(jù)庫和AdventureWorks數(shù)據(jù)庫。(如果你還沒有安裝AdventureWorks數(shù)據(jù)庫的話,你可以從微軟的SQL Server 2005 Samples and Sample Databases下載頁面下載它,還有另外的SQL Server 2005示例。)
5. 把SalesOrderHeader和SalesOrderDetail表拖動到你的DataSet設(shè)計器窗口?,F(xiàn)在,這個窗口應(yīng)該類似于下面的屏幕快照。注意,對于我們加入的每個表,Visual Studio都創(chuàng)建一個強類型DataTable(該名稱是基于原始的表)和一個TableAdapter。這個DataTable為我們定義了每一個列。這個表適配器是我們用來填充這個表的對象。缺省情況下,我們有一個Fill()方法,由它找到表中的每一行。

這個強類型DataSet將返回在這兩個表中的所有記錄。既然AdventureWorks 這個SQL查詢是一個簡單的SELECT查詢,它有一個@OrderDate參數(shù)以進(jìn)一步縮小結(jié)果范圍。這樣可以防止我們返回 四、 在一個ASP.NET頁面上使用強類型DataSet 這段代碼是很簡單的。我們創(chuàng)建SalesOrderHeaderTableAdapter的一個實例-我們將使用它來填充DataTable。注意,不是聲明一個泛型DataTable,我們聲明了一個SalesOrderHeaderDataTable類型的對象。為了填充這個DataTable,我們調(diào)用GetDateBy()方法并且傳遞給它一個DateTime對象。還要注意,甚至這個檢索命令也是強類型化的,因為我們必須傳遞一個DateTime對象,而不僅僅是一個泛型對象。下面的屏幕快照顯示了上面示例代碼的清晰結(jié)果。
SalesOrderID, RevisionNumber, OrderDate, DueDate, ShipDate,
Status, OnlineOrderFlag, SalesOrderNumber, PurchaseOrderNumber,
AccountNumber, CustomerID, ContactID, SalesPersonID, TerritoryID,
BillToAddressID, ShipToAddressID, ShipMethodID, CreditCardID,
CreditCardApprovalCode, CurrencyRateID, SubTotal, TaxAmt, Freight,
TotalDue, Comment, rowguid, ModifiedDate
FROM Sales.SalesOrderHeader
WHERE (OrderDate > @OrderDate)
通過創(chuàng)建強類型DataSet,我們可以僅通過編寫幾行代碼就可以實現(xiàn)容易地在一個ASP.NET頁面顯示這些數(shù)據(jù)。首先,在你的網(wǎng)站上創(chuàng)建一個ASP.NET頁面并且在設(shè)計模式中觀察它。然后,拖放一個GridView控件到其上,保持其ID為GridView1。打開ASP.NET頁面的源代碼并且在文件的頂部導(dǎo)入AdventureWorksTableAdapters命名空間(在C#中,該語法為:"using AdventureWorksTableAdapters;")。最后,把下列代碼添加到Page_Load事件處理器中:
SalesOrderHeaderTableAdapter salesAdapter =
new SalesOrderHeaderTableAdapter();
//得到發(fā)生于2004年7月1日之后的訂單
AdventureWorks.SalesOrderHeaderDataTable Orders =
salesAdapter.GetDataBy(new DateTime(2004, 7, 1));
//把訂單結(jié)果綁定到GridView
this.GridView1.DataSource = Orders;
this.GridView1.DataBind();
除了通過代碼把結(jié)果綁定到GridView外,你還可以使用一個ObjectDataSource,設(shè)置它的TypeName屬性為AdventureWorksTableAdapters.SalesOrderHeaderTableAdapter,并且把它的SelectMethod設(shè)置為GetData或GetDataBy。
五、 使用強類型DataSet插入、更新和刪除數(shù)據(jù)
在本文中,我們已經(jīng)看到了怎樣使用一個強類型DataSet從一個數(shù)據(jù)庫中選擇數(shù)據(jù)。然而,你還可以使用這些工具來插入、更新和刪除基本的數(shù)據(jù)庫數(shù)據(jù)。
除了不必編寫代碼來存取數(shù)據(jù)庫外,使用這個強類型化的DataSet的另外一個很大的優(yōu)點是,在此不存在編譯器不能檢查的字符串列名潛伏在我們的代碼并且我們不必進(jìn)行任何對象轉(zhuǎn)換。如果我們曾經(jīng)改變過我們的數(shù)據(jù)庫模式,那么一旦我們更新我們的AdventureWorks.xsd文件,我們將注意到在編譯期間的存在于我們的應(yīng)用程序中的所有的巨大變化。
六、 小結(jié)
其實,除了使用強類型DataSet外,還有另外的方法來實現(xiàn)你的應(yīng)用程序的強類型化。你可以創(chuàng)建定制類-比DataSet更為輕量級并且能夠正確地響應(yīng)于你的數(shù)據(jù)庫。而且,還有一些第三方軟件開發(fā)者提供工具來自動化這一過程。其中,一個特別的產(chǎn)品是LLBLGen Pro,就是我比較喜歡的工具之一,我還寫了有關(guān)于它的一本書:《Rapid C# Windows Development: Visual Studio 2005, SQL Server 2005,and LLBLGen Pro》。另外一個流行的工具是CodeSmith。甚至微軟也在使用一個與之類似的工具-DLINQ,它仍處于測試階段,至少在下一年中不會上市。
如果你使用Visual Studio強類型DataSet方法,那么你不需要購買任何另外的軟件-這是一個明顯的優(yōu)點。所有這些解決方案都有其各自不同的特征和優(yōu)點,但是強類型化你的關(guān)系數(shù)據(jù)的主要優(yōu)點還在于:可靠性,更少的錯誤和更少的調(diào)試時間花費;另外,分析數(shù)據(jù)庫模式變化的影響并實現(xiàn)它們也更為容易。最后,非常希望你已經(jīng)了解到強類型化的優(yōu)點。祝你幸運!