小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Builder.com.cn-編程-Visual Studio 2005 中的新的 DataSet 功能

 freezn 2006-01-06

Visual Studio 2005 中的新的 DataSet 功能
作者: Jackie Goldstein
2005-10-11 11:40 AM

除非另有說明,否則本文的內(nèi)容基于 Visual Studio 2005 的 2004 年 12 月的 CTP(社區(qū)技術(shù)預(yù)覽)版。

引言

在上一篇文章 ADO.NET 2.0 中的新增 DataSet 功能中,我介紹了即將對 ADO.NET 的 DataSet 類及相關(guān)類(例如 DataSet、DataTable 和 DataView)進(jìn)行的更改及改進(jìn)。所有這些類都是 Microsoft .NET Framework 基類庫的一部分。

在本文中,我將重點介紹從 Microsoft Visual Studio 2005 開發(fā)環(huán)境中使用這些類以及衍生類進(jìn)行開發(fā)的問題。本文特別討論了對 Visual Studio 2005 生成的類型化的 DataSet 類和新的類型化的 TableAdapter 類所做的更改。本文還介紹了一些設(shè)計器和工具,它們?yōu)殚_發(fā)以數(shù)據(jù)為中心的應(yīng)用程序功能提供了極大的靈活性和效率。為了解釋不同的概念和功能,我將逐步介紹開發(fā)人員在實現(xiàn)應(yīng)用程序的數(shù)據(jù)部分時通常會經(jīng)歷的過程。本文中的代碼示例使用 Northwind 數(shù)據(jù)庫,該數(shù)據(jù)庫是 Microsoft SQL Server(及 MSDE)7.0 和 2000 附帶的示例數(shù)據(jù)庫。

數(shù)據(jù)源

Visual Studio 2005 引入了項目的數(shù)據(jù)源概念。數(shù)據(jù)源表示可供應(yīng)用程序使用的數(shù)據(jù)。這些數(shù)據(jù)不一定來自數(shù)據(jù)庫,用來定義數(shù)據(jù)源的“數(shù)據(jù)源配置向?qū)?#8221;允許您從三個不同的來源獲得數(shù)據(jù):

1.數(shù)據(jù)庫 - 可以是基于服務(wù)器的數(shù)據(jù)庫,例如 SQL Server 或 Oracle;也可以是基于文件的數(shù)據(jù)庫,例如 Access 或 SQL Server Express。Visual Studio 可以自動生成類型化的 DataSet 和其他類,并將它們添加到您的項目中。

2.對象 - 具有公共屬性的任何對象都可以作為數(shù)據(jù)源,不需要實現(xiàn)任何特殊的接口。 3.Web 服務(wù) - 通過 Web 服務(wù)創(chuàng)建數(shù)據(jù)源將創(chuàng)建一些與 Web 服務(wù)返回的數(shù)據(jù)類型相對應(yīng)的對象。

數(shù)據(jù)源的用途包括兩方面。首先,它作為一種方法,使指定、設(shè)計和生成強(qiáng)類型的類(用于表示應(yīng)用程序的數(shù)據(jù))變得更容易。其次,它提供了一種靈活但統(tǒng)一的機(jī)制,可以快速創(chuàng)建豐富且功能強(qiáng)大的 WinForm 和 WebForm 用戶界面。閱讀本文后,就會了解此過程是多么快速、簡單和靈活。

在本文中,我們將重點介紹如何創(chuàng)建數(shù)據(jù)庫 (DataSet) 數(shù)據(jù)源,以及如何在 WinForm 應(yīng)用程序中使用它們。但是,記住以下兩點很重要:

創(chuàng)建數(shù)據(jù)源后,不管它的數(shù)據(jù)來自何處,使用它的方式都是相同的。也就是說,就像您可以輕松(且圖形化)地將基于數(shù)據(jù)庫的數(shù)據(jù)源綁定到一個網(wǎng)格或一組控件一樣,實際上來自 Web 服務(wù)或自定義業(yè)務(wù)對象的數(shù)據(jù)也是如此。

數(shù)據(jù)源以相同的方式進(jìn)行定義,不管它們將要用在 WinForm 應(yīng)用程序還是 WebForm 應(yīng)用程序中。不同的數(shù)據(jù)提供程序還可以抽象化,所以如果只使用 DataSet 和 TableAdapter 提供數(shù)據(jù)訪問,要更改實際的數(shù)據(jù)庫,只需更改連接字符串并重新生成類即可。

類型化的 DataSet 和 TableAdapter

一個數(shù)據(jù)庫數(shù)據(jù)源是一個強(qiáng)類型的 DataSet 與一對或多對強(qiáng)類型的 DataTable 和 TableAdapter 的組合。類型化的 DataSet 并不是一個新概念,我們曾在 Visual Studio 2002/2003 中討論過它。類型化的 DataSet 是一個生成的類,是從 .NET Framework 的一般 DataSet 類衍生來的,但具有已定義的架構(gòu)以及特定于該架構(gòu)的屬性和方法。同時,對于 DataSet 中的每個表,還生成了特定于該 DataSet 的三個附加衍生類:DataTable、DataRow 和 DataRowChangeEvent。每個類都為相關(guān)的表提供了特定的架構(gòu)、屬性和方法。例如,如果我定義一個基于 Northwind Employees 表的數(shù)據(jù)源,最后會生成以下類:

• NorthwindDataSet

EmployeesDataTable

• EmployeesDataRow

• EmployeesRowChangeEvent

這四個類組成了類型化的 DataSet。在 Visual Studio 2005 中,還會生成第五個類,即名為 EmployeesTableAdapter 的類型化的 TableAdapter 類,我們稍后會進(jìn)行討論。當(dāng)然,如果您動態(tài)定義查詢,則不能生成類型化的 DataSet,而需要使用標(biāo)準(zhǔn)的 DataSet。

為什么非要使用類型化的DataSet 呢?除了強(qiáng)迫您事先仔細(xì)考慮數(shù)據(jù)架構(gòu)的問題,而不是只“隨便想想”之外,類型化的 DataSet 還提供了以下幾個具體的優(yōu)點:

1.DataSet、DataTable、DataRow 和 RowChangeEvent 特定于要處理的架構(gòu)。

2.表、列和關(guān)系是作為命名屬性提供的,而不是作為一般的集合元素。

3.作為第 (2) 條的結(jié)果,您可以從 Visual Studio 代碼編輯器中獲得全部的 IntelliSense 和語句完成支持。

4.同樣作為第 (2) 條的結(jié)果,使編譯時類型檢查成為可能(例如,可以在編譯時而不是運行時捕獲字段名稱拼寫錯誤)。

5.代碼更簡潔、可讀性更強(qiáng),不會出現(xiàn)這樣的代碼:

country = dsNorthwind.Tables ("Employees").Rows (row) ("Country")

相反,代碼應(yīng)是:

country = dsNorthwind.Employees (row).Country

最基本的是,類型化的 DataSet 提供的設(shè)計時和編譯時幫助不僅可以大大減少最初的開發(fā)時間,還可以大大減少調(diào)試和穩(wěn)定應(yīng)用程序所需的時間。

而 TableAdapter 對 Visual Studio 2005 來說則是一個全新的概念。它隱含的意思是,強(qiáng)類型的 TableAdapter 是標(biāo)準(zhǔn) DataAdapter 的強(qiáng)類型的等價物。您使用 TableAdapter 連接數(shù)據(jù)庫并對該數(shù)據(jù)庫執(zhí)行查詢(或存儲過程),然后用數(shù)據(jù)填充相關(guān)的 DataTable。每個 DataTable-TableAdapter 對簡稱為一個 TableAdapter。

注意:在 2004 年 12 月的 CTP 中,DataTable-TableAdapter 對被稱為數(shù)據(jù)組件。但是,Visual Studio 已不再使用此術(shù)語,以后的版本中只會將該對稱為 TableAdapter。本文只使用術(shù)語 TableAdapter。

TableAdapter 實質(zhì)上是標(biāo)準(zhǔn) DataAdapter 的包裝程序,它具有以下幾個優(yōu)點:

• 同一個 TableAdapter 類可用于多個表單或組件中,使查詢/命令的任何更改都能自動反映在所有實例中。這與現(xiàn)狀是不同的,現(xiàn)在,訪問數(shù)據(jù)庫的每個組件都必須具有自己單獨配置的 DataAdapter。這使 DataTable 和 DataAdapter 之間的同步更容易實現(xiàn)。

• TableAdapter 使您可以輕松地為一個給定的 DataTable 定義多個命令,而不必使用多個 DataAdapter(或手動編寫的切換代碼)為一個 DataTable 定義多個查詢/命令。

• 填充命令具有可讀(友好)的名稱,而且 TableAdapter 包含的代碼能夠自動將所有參數(shù)的類型和值信息填充到這些命令方法中。您不用再擔(dān)心如何傳遞提供程序特定的數(shù)據(jù)類型(例如 SqlInt)。

一個簡單的代碼片斷將有助于說明這些功能。在 Visual Studio 2002/2003 中,即使使用類型化的 DataSet,使用兩個參數(shù)執(zhí)行一個簡單查詢的代碼對查詢來說也很重要:

SELECT FirstName, LastName from Employees WHERE Country = @country AND City = @city

我們必須編寫如下所示的代碼:

Me.SqlAdapter1.SelectCommand.Parameters ("@country").value =
Me.CountryListbox.SelectedValue.Trim()
Me.SqlAdapter1.SelectCommand.Parameters ("@city").value =
Me.CityTextbox.Text.Trim()
Me.SqlAdapter1.Fill (Me.NorthwindDataSet.Employees)

當(dāng)然,隨著參數(shù)數(shù)量的增加,代碼的行數(shù)也會增加。更重要的是,正確記住并鍵入每個參數(shù)名稱的可能性大大降低。即使參數(shù)名稱正確,我還需要記住該參數(shù)的數(shù)據(jù)類型。最慘的是,如果我輸入了錯誤的字段名稱或者嘗試指定了錯誤類型的值,直到運行時才能發(fā)現(xiàn)這個錯誤!

使用 Visual Studio 2005 中的 TableAdapter,定義命令 FillByCountryAndCity 之后,我只需編寫一行代碼(用于傳遞參數(shù)值),即可在任意位置使用該命令:

Me.EmployeesTableAdapter.FillByCountryAndCity ( _
Me.NorthwindDataSet.Employees, Me.CountryListbox.SelectedValue.Trim(), _ Me.CityTextbox.Text.Trim() )

請務(wù)必注意,我們不僅是從一個 TableAdapter 中獲取多個命名命令,而且這些命令是強(qiáng)類型的。這意味著在 Visual Studio 中編寫代碼時,我們可以獲得全部的 IntelliSense,能夠?qū)⑦@些命令視為 TableAdapter 的方法。我們還可以對這些命令的參數(shù)進(jìn)行編譯時類型檢查,還可以獲得帶有方法和參數(shù)類型定義的工具提示以幫助我們處理各種情況。TableAdapter 可以有多個方法,用來執(zhí)行不同的命令并接受不同的參數(shù)。我們將在稍后創(chuàng)建示例表單時進(jìn)一步介紹 TableAdapter。

入門 - 創(chuàng)建數(shù)據(jù)源

在本文中,我們將創(chuàng)建一個表單,用來顯示 Northwind 數(shù)據(jù)庫中每個訂單的訂單信息。打開一個新的 Visual Basic WinForm 項目后,首先要做的是在該項目中添加一個新的數(shù)據(jù)源(我們將使用 Visual Basic 逐步介紹此過程,但所有內(nèi)容同樣適用于 C#)。

添加數(shù)據(jù)源的步驟:

1.從 Visual Studio 主菜單的 Data(數(shù)據(jù))菜單項中選擇 Show Data Sources(顯示數(shù)據(jù)源),以顯示 Data Sources(數(shù)據(jù)源)窗口(如果尚未顯示)。

2.在 Data Sources(數(shù)據(jù)源)窗口中,單擊 Add New Data Source(添加新數(shù)據(jù)源)工具欄按鈕。將啟動 Data Source Configuration Wizard(數(shù)據(jù)源配置向?qū)В撓驅(qū)Ш喜⒘?DataAdapter Configuration Wizard(DataAdapter 配置向?qū)В┑拇蠖鄶?shù)功能與 Visual Studio 2002/2003 中的 DataSet 生成工具。

3.如果您的 Visual Studio 版本仍然包含向?qū)У?Welcome(歡迎)頁面,請選擇“下一步”。將顯示 Choose a Data Source Type(選擇數(shù)據(jù)源類型)頁面。

4.選擇 Database(數(shù)據(jù)庫)。

5.選擇 Next(下一步)。將顯示 Choose Your Data Connection(選擇您的數(shù)據(jù)連接)頁面。

6.選擇 New Connection(新建連接)。將顯示 Add Connection(添加連接)對話框。

7.輸入連接 SQL Server 或 MSDE 實例及 Northwind 數(shù)據(jù)庫所需的信息。

8.選擇 OK(確定)關(guān)閉該對話框。

9.請注意,連接字符串現(xiàn)在被保存為設(shè)置屬性,可以通過以下字符串進(jìn)行訪問:

My.Settings.NorthwindConnectionString

在 C# 中,該字符串應(yīng)為:

VSDataSets.Properties.Settings.Default.NorthwindConnectionString;

10.選擇 Next(下一步)。將顯示 Choose Your Database Objects(選擇您的數(shù)據(jù)庫對象)頁面。

11.請注意,您可以從 Tables(表)、Views(視圖)、Stored Procedures(存儲過程)或 Functions(函數(shù))中進(jìn)行選擇。

展開 Tables(表)節(jié)點,然后選擇 Orders 和 Order Details 表。我們將使用表中的所有列,但您可以只選擇您的應(yīng)用程序需要的那些列。

12.選擇 Finish(完成)退出向?qū)А?

圖 1 顯示了生成的 Data Sources(數(shù)據(jù)源)窗口,其中的 Order Details 表已展開以顯示表中的所有列。

圖 1:Data Sources(數(shù)據(jù)源)窗口中的 Order Details 表

如果要重新打開 Data Source Configuration Wizard(數(shù)據(jù)源配置向?qū)В┮赃M(jìn)行某些更改,可以從 Data Sources(數(shù)據(jù)源)窗口的工具欄或者從右鍵單擊該窗口中的任意元素后顯示的上下文菜單中選擇 Configure DataSet with Wizard(使用向?qū)渲?DataSet)。但是,還有一個更強(qiáng)大的工具可用來編輯生成的 DataSet 和 TableAdapter,那就是 DataSet 設(shè)計器。 DataSet 設(shè)計器

Visual Studio 2005 附帶了 DataSet設(shè)計器,此工具實際上是為指定和編輯 DataSet 及其相關(guān)的 TableAdapter 而設(shè)計的。這是針對 Visual Studio 2002/2003 中的問題做出的重大改進(jìn),在 Visual Studio 2002/2003 中,我們必須使用 XML 架構(gòu)編輯器來定義強(qiáng)類型的 DataSet。在 Visual Studio 2005 中,DataSet 和 TableAdapter 定義仍然保存在 .XSD 文件中,而且仍然提供了 XML 編輯器,以便在您確實需要編輯 XML 架構(gòu)時使用。但是,新舊版本之間的相似性僅限于此。目的不在于使 DataSet設(shè)計器支持任意 XSD 文件,而是為了說明它只是一種方便的文件格式。

要打開 DataSet 設(shè)計器,請從 Data Sources(數(shù)據(jù)源)窗口的工具欄或者從右鍵單擊該窗口中的任意元素后顯示的上下文菜單中選擇 Edit DataSet with Designer(使用設(shè)計器編輯 DataSet)。設(shè)計 DataSet 及其 DataTable 時,您可能覺得設(shè)計器與您以前設(shè)計數(shù)據(jù)庫時使用的其他工具很相似。您可以通過以下方法從要連接的數(shù)據(jù)庫中添加一個表:將數(shù)據(jù)庫對象(例如表、視圖或存儲過程)從 Server Explorer(服務(wù)器資源管理器)中拖到設(shè)計器上,或者從設(shè)計器上下文菜單的主 Data(數(shù)據(jù))菜單項中選擇 Add TableAdapter(添加 TableAdapter)以啟動 TableAdapter Configuration Wizard(TableAdapter 配置向?qū)ВS捎?DataSet 也可以包含直接加載且未與數(shù)據(jù)庫連接的表,因此您也可以通過從菜單中選擇 Add DataTable(添加 DataTable)來添加獨立的表。當(dāng)然,您也可以在編輯器中添加和/或重命名列。另一個靈活的功能是,編輯器可以自動識別數(shù)據(jù)庫中各表之間的關(guān)系,并為您定義 DataSet 中各表之間的對應(yīng)關(guān)系。

圖 2 顯示了 DataSet 設(shè)計器中的數(shù)據(jù)源,它由 Orders 表和 Order Details 表組成。請注意,與每個 DataTable 密切相關(guān)的是對應(yīng)的 TableAdapter,它的作用是用數(shù)據(jù)填充表并用這些數(shù)據(jù)的更改更新數(shù)據(jù)庫(后者可選)。

圖 2:數(shù)據(jù)源中的 Orders 和 Order Details 表

TableAdapter Configuration Wizard(TableAdapter 配置向?qū)В?

要在 DataSet 設(shè)計器中啟動 TableAdapter Configuration Wizard(TableAdapter 配置向?qū)Вㄔ?Visual Studio 2005 的 2004 年 12 月的 CTP 版中仍然稱為 Data Component Configuration Wizard [數(shù)據(jù)組件配置向?qū)),請從主 Data(數(shù)據(jù))菜單或從右鍵單擊設(shè)計器中的任意 TableAdapter 時出現(xiàn)的上下文菜單中選擇 Add Query(添加查詢)或 Configure(配置)(現(xiàn)有查詢)。此向?qū)c Visual Studio 2002/2003 中的 DataAdapter Configuration Wizard(DataAdapter 配置向?qū)В┗鞠嗤?,只是多提供了兩個頁面。第一個是圖 3 所示的 Choose a Query Type(選擇查詢類型)頁面。由于 TableAdapter 是給定表中所有命令的中心點,因此它不僅允許您定義多個 Select/Fill 命令,還允許您運行任意類型的查詢(更新、插入、刪除)或只返回一個值的查詢。請注意,這些更新查詢是 TableAdapter 的命名方法,必須直接調(diào)用。它們是您執(zhí)行 TableAdapter 的 Update 方法(就像 DataAdapter.Update 方法一樣)時自動調(diào)用的更新查詢的補(bǔ)充。

向?qū)е械牡诙€附加頁面是 Choose Methods to Generate(選擇要生成的方法)頁面。在此頁面上,您可以為您定義的每個查詢/命令方法選擇名稱。向?qū)槊總€命令都提供了 Fill 和 Get 方法,如圖 3 所示。Fill 方法要求您指定要填充的 DataTable,而 Get 方法將返回新創(chuàng)建和填充的 DataTable。

圖 3:Choose Methods to Generate(選擇要生成的方法)頁面上的 Fill 和 Get 方法

通常情況下,您會為一個 TableAdapter 定義多個 Fill 命令,這些命令返回相同的架構(gòu)(列),但卻具有不同的 WHERE 子句。這就是默認(rèn)情況下向?qū)榉椒Q提供 FillBy 和 GetDataBy 前綴的原因。當(dāng)然,您也可以為方法指定您選擇的任意名稱。

盡管一個 TableAdapter 可以有多個 Fill 命令,但調(diào)用 TableAdapter 的 Update 方法時,只執(zhí)行一組更新命令。這些命令是基于 TableAdapter 的主查詢自動生成的。首次創(chuàng)建 TableAdapter 時定義的查詢被認(rèn)為是 TableAdapter 的主查詢。如果以后定義的任何查詢返回的架構(gòu)與主查詢返回的架構(gòu)不同,設(shè)計器將使用消息框提醒您。此外,如果您修改主查詢的架構(gòu),Visual Studio 將轉(zhuǎn)到并修改其他查詢以匹配該架構(gòu)。

使用 TableAdapter Configuration Wizard(TableAdapter 配置向?qū)В┨砑有旅?

下面,我們將另一個命令添加到 Orders 表的 TableAdapter 中。

1.從 Data Sources(數(shù)據(jù)源)窗口的工具欄中選擇 Edit DataSet with Designer(使用設(shè)計器編輯 DataSet),以打開 DataSet 設(shè)計器。

2.選擇 Orders 表的 TableAdapter,然后從其上下文菜單中選擇 Add Query(添加查詢)。

3.如果您的 Visual Studio 版本中仍然存在 Welcome(歡迎)頁面,請單擊該頁面上的 Next(下一步)。將顯示 Choose a Command Type(選擇命令類型)頁面。

4.選擇 Next(下一步),接受默認(rèn)的 SQL 語句。將顯示 Choose a Query Type(選擇查詢類型)頁面。

5.選擇 Next(下一步),接受默認(rèn)的 SELECT 語句。將顯示 Specify a SQL SELECT Statement(指定 SQL SELECT 語句)頁面。

6.輸入以下 SQL 語句: SELECT OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate, ShippedDate, ShipVia, Freight, ShipName,
ShipAddress, ShipCity, ShipRegion, ShipPostalCode, ShipCountry
FROM Orders
WHERE CustomerID = @CustID

將為查詢返回由 @CustID 參數(shù)指定的客戶的所有訂單。

7.選擇 Next(下一步)。將顯示 Choose Methods to Generate(選擇要生成的方法)頁面。

8.將兩個復(fù)選框保留為選中狀態(tài)。將兩個方法名稱分別修改為 FillByCustomer 和 GetDataByCustomer。

9.選擇 Next(下一步),然后選擇 Finish(完成)以完成該過程。

如果您查看 DataSet 設(shè)計器中的 OrdersTableAdapter,就會看到現(xiàn)在顯示了第二對命令 FillByCustomer 和 GetDataByCustomer,它們使用 CustomerID 值作為參數(shù)。此方法參數(shù)的 (.NET) 類型是什么?讓我們看一看。

后臺查看

在 DataSet 設(shè)計器或任何相關(guān)的向?qū)е羞M(jìn)行更改時,Visual Studio 將轉(zhuǎn)到并為一組類型化的類生成代碼。具體來說,它會生成以下類:

1.DataSet 類
2.DataTable 類
3.TableAdapter 類
4.DataRow 類
5.DataRowChangeEvent 類

除了 DataSet 類(每個數(shù)據(jù)源只有一個)外,DataSet 中定義的每個表都有其他四個類。您可以通過執(zhí)行以下操作來查看這些類的代碼:

1.在 Solution Explorer(解決方案資源管理器)窗口中,單擊工具欄上的 Show All Files(顯示所有文件)按鈕,以顯示與項目相關(guān)的所有文件。

2.展開 NorthwindDataSet.xsd 文件的節(jié)點。

3.雙擊 NorthwindDataSet.Designer.vb 的文件節(jié)點。這就是為實現(xiàn)構(gòu)成 DataSet 的類而生成的代碼。

4.打開代碼窗口左上方的列表框。您可以從中看到此文件中的類列表:

NorthwindDataSet

Order_DetailsDataTable
OrdersDataTable
Order_DetailsRow
OrdersRow
Order_DetailsRowChangeEvent
OrdersRowChangeEvent
Order_DetailsTableAdapter
OrdersTableAdapter

5.從左側(cè)列表框中選擇 OrdersTableAdapter 類。

6.從右側(cè)列表框中選擇 FillByCustomer 方法。將顯示此方法的代碼,如下所示:

Public Overloads Overridable Function FillByCustomer(ByVal dataTable
As NorthwindDataSet.OrdersDataTable, ByVal CustID As String) As Integer
Me.Adapter.SelectCommand = Me.CommandCollection(1)
If (CustID Is Nothing) Then
Throw New System.ArgumentNullException("CustID")
Else
Me.Adapter.SelectCommand.Parameters(0).Value = CType(CustID,String)
End If
If (Me.m_clearBeforeFill = true) Then
dataTable.Clear
End If
Dim returnValue As Integer = Me.Adapter.Fill(dataTable)
Return returnValue
End Function

我們可以從這段代碼中了解幾個問題。

• FillByCustomer 方法實際上使用兩個參數(shù),一個是要填充的 OrdersDataTable,另一個是作為字符串的 CustID 參數(shù)。

• 不必查看文件中的所有代碼就可以看出 TableAdapter 類維護(hù)一個命令集,它自動從該集中將正確的命令指定給 .NET DataAdapter,DataAdapter 實際上用來與數(shù)據(jù)庫通信。

• 方法用于檢查狀態(tài)參數(shù)的實例是否已傳遞給方法(如果參數(shù)的 AllowDBNull 屬性設(shè)置為 False)。

• CustID 參數(shù)值被指定給 DataAdapter 的 SelectCommand 屬性的預(yù)配置參數(shù)。

• 所有內(nèi)容都設(shè)置好之后,將調(diào)用標(biāo)準(zhǔn) DataAdapter.Fill () 方法以填充 OrdersDataTable。 請記住,您不需要自己編寫這段代碼,所有內(nèi)容都已經(jīng)生成并配置好了?;ㄐr間瀏覽一下為其他類生成的代碼,您將會更廣泛且更深入地理解這些類是如何實現(xiàn)的,可能還會學(xué)到一兩個好的編碼方法!

注意:盡管類型化的 DataSet 及其相關(guān)的類(包括 TableAdapter)都在一個源文件中生成,但 TableAdapter 在一個單獨的名稱空間中生成。這反映了這樣一個事實:實體對象 (DataSet) 與實際的數(shù)據(jù)訪問對象 (TableAdapter) 應(yīng)分開。

創(chuàng)建以數(shù)據(jù)為中心的表單

現(xiàn)在已經(jīng)生成了一個類型化的 DataSet,下面我們要創(chuàng)建一個顯示這些數(shù)據(jù)的表單。盡管我不會介紹 .NET Framework 2.0 和 Visual Studio 2005 中的 WinForm 和數(shù)據(jù)綁定的所有細(xì)節(jié)和新功能(要介紹的內(nèi)容有很多),但這是一個好機(jī)會,可以了解為了更輕松靈活地創(chuàng)建以數(shù)據(jù)為中心的功能表單已經(jīng)完成的某些操作。

工具箱中的數(shù)據(jù)組件

如果您習(xí)慣于從工具箱的 Data(數(shù)據(jù))選項卡上的標(biāo)準(zhǔn)數(shù)據(jù)組件開始創(chuàng)建以數(shù)據(jù)為中心的代碼,那么打開 Visual Studio 2005 后看不到這些標(biāo)準(zhǔn)組件會讓您有點失望和迷茫。當(dāng)然,這是“故意的”,Microsoft 要促使我們利用新的類型化的 DataSet 和 TableAdapter。如果您非常希望使用舊的、非類型化的組件,則可以手動將它們添加回工具箱中。強(qiáng)烈建議您不要這樣做,通過利用新的 TableAdapter 以及局部類技術(shù),新的類型化的 DataSet 和 TableAdapter 將更容易使用和展開。

您可以從 Visual Basic 團(tuán)隊網(wǎng)絡(luò)日志中了解有關(guān)這些問題和其他設(shè)計決策(以及做出這些決策的想法)的詳細(xì)信息。

尤其應(yīng)閱讀 Steve Lasker 的兩個帖子:Why are the Data Components no longer on the Toolbox? 和 Why can‘t I drag from Server Explorer to my form?

在 Visual Studio 設(shè)計器中打開一個表單時,Visual Studio 工具箱中將顯示一個標(biāo)有您的項目名稱的選項卡。將數(shù)據(jù)源添加到項目中并且至少編譯一次后,此選項卡上將包含您創(chuàng)建的類型化的 DataSet 和 TableAdapter。盡管您可以將這些組件拖到表單設(shè)計器中,但您通??赡懿粫@樣做(但是,如果您要使用設(shè)計器實現(xiàn)數(shù)據(jù)訪問組件,這卻是一個不錯的方法)。您通常會使用三種不同方法中的一種來創(chuàng)建以數(shù)據(jù)為中心的表單。我們先來詳細(xì)介紹第一種方法,這是最簡單的,可能也是最常用的方法。這就是所謂的“一次拖動”數(shù)據(jù)綁定。

1.雙擊 Solution Explorer(解決方案資源管理器)中的“Form1.vb”,在 Visual Studio 表單設(shè)計器中打開 Form1。

2.在 Data Sources(數(shù)據(jù)源)窗口中,展開 Orders 表的節(jié)點。

請注意,DataSet 中的每個表和每個列都有一個相關(guān)的圖標(biāo)。這些圖標(biāo)表示將表或列拖放到表單中時,用來綁定到數(shù)據(jù)的 WinForm 控件的類型(或“拖放類型”)。通過選擇一個項目并從相關(guān)的下拉列表中選擇一個控件,可以更改控件的類型。請注意,下拉列表中包括選項 None(無,表示未顯示任何內(nèi)容)和 Customize(自定義,表示可以指定任意控件)。

只有當(dāng)前活動的窗口為表單(或組件)設(shè)計器時,這些圖標(biāo)和拖放類型列表才可見。否則,您將無法從 Data Sources(數(shù)據(jù)源)窗口中拖放控件,這些圖標(biāo)也會發(fā)生變化,向您指明這一點。

3.將 Orders 表的控件類型從 DataGridView 更改為 Details。這意味著當(dāng)您將整個 Orders 表拖動到一個表單上時,系統(tǒng)將創(chuàng)建一個逐行顯示詳細(xì)信息的表單,而不是創(chuàng)建一個在一個網(wǎng)格中顯示所有數(shù)據(jù)(一次顯示所有行)的表單。對于 Details(詳細(xì)信息)視圖,將為每一列添加一個標(biāo)簽和一個控件,控件的類型在 Data Sources(數(shù)據(jù)源)窗口中指定。

4.將 Orders 表從 Data Sources(數(shù)據(jù)源)窗口拖動到設(shè)計器中的 Form1 上。

5.選擇最后七 (7) 個字段(以及它們的標(biāo)簽),然后將這些字段拖到前七 (7) 個字段的旁邊,使表單如圖 4 所示。

圖 4:設(shè)計器中的 Form1

6.啟動應(yīng)用程序,然后使用表單頂部的工具欄上的導(dǎo)航按鈕逐個查看記錄,驗證該應(yīng)用程序能否正常工作。

我們來看一看將 Data Source 表拖到表單上后,Visual Studio 執(zhí)行了哪些操作。查看表單下面的組件欄,可以看到它向表單中添加了四個組件。我們已經(jīng)了解(或許已經(jīng)喜歡上)其中的兩個組件:NorthwindDataSet 和 OrdersTableAdapter。OrdersTableAdapter 用于使用數(shù)據(jù)庫中的數(shù)據(jù)填充 NorthwindDataSet 的 OrdersDataTable。甚至執(zhí)行此 Fill 操作的一行代碼也已經(jīng)編寫并自動添加到 Form1 的 Load 事件處理程序中。

Me.OrdersTableAdapter.Fill(Me.NorthwindDataSet.Orders)

用于數(shù)據(jù)綁定的關(guān)鍵類是 BindingSource 類,它在本例中被明確命名為 OrdersBindingSource。BindingSource(在 Beta 1 中稱為 DataConnector)提供將控件綁定到表單所需要的服務(wù)。它在數(shù)據(jù)源和綁定到該數(shù)據(jù)源的控件之間提供了一個非直接層。通過設(shè)置 BindingSource 的 DataSource 和 DataMember 屬性,將 BindingSource 附著到一個數(shù)據(jù)源上;然后通過添加到控件的 DataBindings 集合中,將這些控件綁定到 BindingSource。與數(shù)據(jù)進(jìn)行的所有交互(例如記錄的導(dǎo)航、排序、篩選和編輯)都是通過 BindingSource 完成的。BindingSource 還通過 List、Item 和 Current 屬性允許訪問基礎(chǔ)數(shù)據(jù)。

添加的另一個組件是 OrdersBindingNavigator。BindingNavigator 類是一個工具欄,它為導(dǎo)航和操作表單上的數(shù)據(jù)提供了一個標(biāo)準(zhǔn)的用戶界面。BindingNavigator(在 Beta 1 中稱為 DataNavigator)是一個 ToolStrip 控件,它具有一組預(yù)配置的按鈕。它附著到作為其數(shù)據(jù)源的 BindingSource 上,并提供控制導(dǎo)航可用數(shù)據(jù)的工具欄按鈕。但是,如果您不想控制導(dǎo)航,而是希望響應(yīng)某些導(dǎo)航事件,則應(yīng)連接 BindingSource 對象的這些事件。

創(chuàng)建一個“主表單-詳細(xì)信息”表單

現(xiàn)在,我們已經(jīng)創(chuàng)建了一個可以顯示一個表中的數(shù)據(jù)的表單,那么以“主表單-詳細(xì)信息”的格式顯示第二個相關(guān)表中的數(shù)據(jù)容易(或困難)嗎?只需繼續(xù)在 Form1 中執(zhí)行以下步驟: 1.現(xiàn)在,我們將使用“連接點”數(shù)據(jù)綁定來創(chuàng)建表單,并將一個控件從工具箱中拖放到該表單上,然后將 Data Source(數(shù)據(jù)源)窗口中的一個元素拖放到該控件上,將控件和元素連接起來。

2.從工具箱的 All Windows Forms(所有 Windows 表單)選項卡上選擇 DataGridView 控件。將該控件拖放到 Form1 上,使其占據(jù)表單下半部分的大部分空間。

3.返回到 Data Source(數(shù)據(jù)源)窗口,如圖 5 所示。請注意,Order Details 表實際上在該窗口中出現(xiàn)兩次。第一次,它作為 NorthwindDataSet 的直接子控件和 Orders 表的同級控件。第二次,它顯示為 Orders 表的子控件,表明它是一個相關(guān)表。如果要在表單上單獨顯示 Order Details 表,則可以選擇直接位于 NorthwindDataSet 下的 Order Details 表的實例。但在本例中,我們要顯示與(主)Orders 表相關(guān)的 Order Details 表,因此,我們應(yīng)選擇顯示直接位于 Orders 表下的 Order Details 表的實例。

圖 5:Data Source(數(shù)據(jù)源)窗口中的 Order Details 表

4.選擇 Orders 表下的 Order Details 表,然后將其拖動到 Form1 中的 DataGridView 上。

5.請注意,Order_DetailsBindingSource 和 Order_detailsTableAdapter 已被添加到 Form1 的組件欄中。

6.運行應(yīng)用程序,并使用 BindingNavigator 瀏覽 Orders 表中的記錄,如圖 6 所示。請注意,DataViewGrid 中顯示的 Order Details 記錄將自動發(fā)生變化,以便只顯示與當(dāng)前 Order 記錄相關(guān)的那些記錄。

圖 6:Orders 表中的 BindingNavigator

由于某些原因,“連接點”數(shù)據(jù)綁定在 Visual Studio 2005 的 2004 年 12 月 CTP 版中是斷開的。但是,它在 Visual Studio 2005 以前和以后的版本中都能正確工作。如果您使用的是 12 月的 CTP 版,只需將 Order Details 表(位于 Orders 表下)拖放到 Form1 中。

自定義生成的代碼

在前面我們查看 DataSet 的類的代碼時,您可能已經(jīng)注意到了實際上有兩個 Visual Basic 代碼文件:NorthwindDataSet.Designer.vb 和 NorthwindDataSet.vb。如果沒有 NorthwindDataSet.vb 文件,請返回到 DataSet 設(shè)計器,雙擊該設(shè)計器的背景以創(chuàng)建該文件。

這兩個文件都用來實現(xiàn)構(gòu)成 DataSet 的類。存在兩個文件的原因在于,我們要利用一個新的、簡單但很強(qiáng)大的功能,稱為局部類。局部類是一個編譯器功能,它允許將類(或結(jié)構(gòu))的定義拆分到幾個聲明中。不同的聲明可以位于不同的源代碼文件中,只要這些聲明都位于相同的程序集和名稱空間中就可以。Visual Studio 廣泛使用此功能,將設(shè)計器和開發(fā)人員為同一個類生成/編寫的代碼分開。例如,在 Visual Studio 2002/2003 中,表單的代碼可能是該表單的類聲明的所有內(nèi)容,例如:

Public Class Form1
Inherits System.Windows.Forms.Form

該表單的初始化代碼(包括該表單上放置的所有控件)都由 Visual Studio 生成。這段代碼位于 InitComponent () 方法中,默認(rèn)情況下,出現(xiàn)在名為“Windows 表單設(shè)計器生成的代碼”代碼區(qū)域中用戶編寫的代碼之前。此區(qū)域通常是閉合的,以便最大程度地減少這段代碼對您實際要編寫的代碼造成的混亂和干擾。在 Visual Studio 2005 中,這段代碼造成的干擾更少,因為它包含在一個名為 Form1.Designer.vb 的完全不同的文件中!同樣,如果您愿意,仍然可以查看該文件的內(nèi)容:單擊 Solution Explorer(解決方案資源管理器)工具欄上的 Show All Files(顯示所有文件),展開 Form1.vb 節(jié)點,然后雙擊 Form1.Designer.vb,使其顯示在代碼編輯器中。文件 Form1.vb 中只包含您作為開發(fā)人員為 Form1 類編寫的代碼。

對于 DataSet 及相關(guān)類的代碼,使用局部類和不同的文件將設(shè)計器代碼和開發(fā)人員代碼相分離就變得更加重要。除了更加有序外,這種分離還解決了在 Visual Studio 2002/2003 中使用類型化的 DataSet 時存在的一個大問題。

您經(jīng)常希望對系統(tǒng)自動為 DataSet 及其相關(guān)類生成的代碼進(jìn)行擴(kuò)展或添加,例如添加附加屬性或自定義驗證代碼。盡管您仍然可以向生成的代碼中添加這些內(nèi)容,但當(dāng)您更改架構(gòu)并且需要重新生成 DataSet 代碼時,將會遇到問題。在 Visual Studio 2002/2003 中,由于您的代碼只是添加到包含生成的代碼的文件中,因此在重新生成代碼時,您添加的所有附加代碼都將被刪除。由于使用了局部類,Visual Studio 2005 中不會再出現(xiàn)此問題。新生成的代碼將覆蓋擴(kuò)展名為 .Designer.vb 的文件中的現(xiàn)有設(shè)計器代碼,但是 .vb 文件中由開發(fā)人員編寫的代碼則保持不變。

使用局部類擴(kuò)展 DataSet 功能的方法之一就是添加自定義驗證代碼。這是向生成的類型化的 DataSet 中添加某些應(yīng)用程序特定的邏輯的機(jī)會。我們向 NorthwindDataSet 中的 Orders 表的新行中添加自定義驗證和初始化。添加新行時,需要檢驗傳遞的郵政編碼值是否確實屬于傳遞的城市。如果不是,就要將 ShipPostalCode 字段的值更改為 Invalid。如果提供的郵政編碼確實屬于提供的城市,則假設(shè)有一個函數(shù)實現(xiàn)返回 True,如下所示:

Function IsPostalCodeInCity (ByVal PostalCode as string, ByVal City as string) As Boolean

我們可以通過執(zhí)行以下操作將該項檢查添加到我們的 NorthwindDataSet 中:

1.在 Data Sources(數(shù)據(jù)源)窗口的工具欄中選擇 Edit DataSet with Designer(使用設(shè)計器編輯 DataSet),以打開 DataSet 設(shè)計器。

2.雙擊設(shè)計器背景中的空白區(qū)域。將在代碼編輯器中打開 NorthwindDataSet.vb 文件。

3.輸入以下代碼而不是默認(rèn)代碼:

Partial Public Class NorthwindDataSet
Partial Class OrdersDataTable
Protected Sub ValidateNewRow(ByVal sender As Object, _
ByVal e As System.Data.DataTableNewRowEventArgs) _
Handles Me.TableNewRow
‘ 創(chuàng)建行的類型化實例
‘ 這可以幫助我們避免將代碼放在引號中,
‘ 例如 e.Row("ShipPostalCode")
Dim ordersRow As NorthwindDataSet.OrdersRow
ordersRow = e.Row
If Not ordersRow.IsShipPostalCodeNull And _
Not ordersRow.IsShipCityNull Then
If Not IsPostalCodeInCity(ordersRow.ShipPostalCode, _
ordersRow.ShipCity) Then
‘ 設(shè)置 ShipPostalCode 的值
ordersRow.ShipPostalCode = "Invalid"
‘ 通常,更改用戶數(shù)據(jù)是不好的用戶體驗
‘ 因此使用 ErrorProvider 指明錯誤
‘ 這里我們介紹了兩種方法
ordersRow.SetColumnError( _
ShipPostalCodeColumn.ColumnName, "Invalid Postal Code")
Else
‘ 當(dāng)值為 valid 時,我們總是需要重置錯誤
ordersRow.SetColumnError( _
ShipPostalCodeColumn.ColumnName, String.Empty)
End If
End If
End Sub
End Class
Private Shared Function IsPostalCodeInCity(ByVal postalCode As String, _
ByVal city As String) As Boolean
‘ 這是一個存根,只是為了驗證功能
If city = "Rio de Janeiro" Then
Return False
Else
Return True
End If
End Function
End Class

請注意,DataSet 的所有相關(guān)類(例如 OrdersDataTable)都是作為 DataSet 中的嵌套類實現(xiàn)的。前面代碼中顯示的局部類聲明反映了這種實現(xiàn)。

為了獲得錯誤提供程序指示的錯誤,除了將郵政編碼值更改為 Invalid 外(也可以不更改),還需執(zhí)行以下操作:

1.將 Error Provider 控件從工具箱拖到 Form1 上,將其放在 Ship Postal Code 文本框的右側(cè)。

2.在 Error Provider 的屬性窗口中,將 DataSource 屬性設(shè)置為 OrdersBindingSource。 運行應(yīng)用程序,然后導(dǎo)航到城市 Rio de Janeiro 的記錄,查看當(dāng)前運行的驗證代碼,如圖 7 所示。

圖 7:Error Provider 控件

這個示例只是為了說明如何輕松地擴(kuò)展 Visual Studio 自動生成的類型化的 DataSet 及相關(guān)類的功能。您可能還需要向生成的類中添加其他方法和屬性。在設(shè)計應(yīng)用程序和使用 DataSet 時,您會想到更多的可能性。需要記住的關(guān)鍵點是,由于 Visual Studio 2005 中使用了局部類,您編寫的代碼位于一個單獨的文件中,重新生成 DataSet 類時不會受到影響。

小結(jié)

使用 Visual Studio 2005 生成的類型化的 DataSet 比以往更容易、更靈活。DataSet設(shè)計器為定義 DataSet 提供了一個更容易、更自然的工具。新的 TableAdapter 類(可以在 DataSet設(shè)計器中進(jìn)行配置)提供了一個集中的機(jī)制,使您可以對特定的數(shù)據(jù)表輕松地維護(hù)和執(zhí)行多個不同的查詢和命令。使用局部類編譯器功能使設(shè)計器生成的代碼與開發(fā)人員編寫的代碼完全分離,重新生成 DataSet 類時將不會影響為了擴(kuò)展這些類而編寫的任何自定義代碼。最后,新的 .NET 數(shù)據(jù)綁定類和機(jī)制與 Visual Studio 2005 提供的工具相結(jié)合,使開發(fā)以數(shù)據(jù)為中心的應(yīng)用程序變得更容易、更快捷。

感謝 Steve Lasker 以及 Microsoft 的 Alan Griver 和 Pablo Castro 為本文的誕生提供的幫助。

關(guān)于作者

Jackie Goldstein 是 Renaissance Computer Systems的負(fù)責(zé)人,該公司專門從事 Microsoft 工具和技術(shù)的咨詢、培訓(xùn)和開發(fā)。Jackie 是 Microsoft 的一位區(qū)域總監(jiān),還是Israel Visual Basic User Group 的創(chuàng)始人以及國際開發(fā)人員事件(包括 TechEd、VSLive!、Developer Days 和 Microsoft PDC)的專題演講者。他還是《Database Access with Visual Basic.NET》(Addison-Wesley,ISBN 0-67232-3435)一書的作者以及 INETA Speakers Bureau 的成員。2003 年 12月,Microsoft 授予了 Jackie“.NET 軟件傳奇人物”的稱號!

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多