體驗ASP.NET2.0中的數據訪問控件
簡介
數據訪問一直是開發 Web 應用程序的一個關鍵問題。幾乎每個商業應用程序都需要數據驅動的 Web 頁面。由于數據訪問如此普遍,開發人員不斷地為簡單的數據庫任務重新生成復雜的代碼就顯得毫無意義了。開發人員需要從格式各異的不同數據源中快速訪問數據。幸運的是,ASP.NET 2.0 中新增的數據訪問控件和 ADO.NET 2.0 解決了這一問題。
對于傳統的 ASP 和 ASP.NET 1.1 應用程序而言,開發人員不得不創建代碼訪問和更新數據庫,將檢索到的數據轉換為瀏覽器識別的 HTML 格式。盡管 Visual Studio .NET 的向導可以幫助完成這個任務,但是要完成諸如分頁和排序這樣的高級功能,仍需要在后端代碼和前端顯示之間進行復雜的同步。通常,這樣的代碼難以維護和同步,特別是在數據庫發生更改或需要在頁面上顯示附加數據的時候。此外,作為數據存儲,XML 需要添加大量混有數據訪問邏輯的代碼。
為了提高開發人員的開發效率和 Web 應用程序的性能,ASP.NET 2.0 通過新增的數據控件中封裝的功能,更加靈活地控制數據,從而減少訪問和顯示數據所需的代碼。從傳統的數據庫到 XML 數據存儲,各種各樣的數據源都能連接到這些控件。所有數據源都以相似的格式進行處理,大大地降低了開發數據驅動的應用程序的復雜性。ASP.NET 2.0 需要進行廣泛的體系結構改進,以便從內部支持這些功能。新增的數據源對象通過業界認可的最佳方法增加了一個非常可靠的基礎結構。現在,大多數復雜的應用程序都可以利用 ASP.NET 2.0 提供的數據訪問工具。從體系結構和機制上限制 ASP.NET 1.x 執行的綁定和緩存問題,在 ASP.NET 2.0 中都得以解決了。
如果您是一位 ASP 開發人員,那么您會通過這篇白皮書了解到 ASP.NET 2.0 新增的數據訪問功能和 ADO.NET 2.0 的數據訪問模型。如果您是一位 ASP.NET 1.1 的開發人員,那么這篇白皮書概括的 ADO.NET 新增的改進功能和數據訪問模型,以及介紹的如何使用 ASP.NET 2.0 新增的數據訪問控件將幫助您減少開發數據驅動 Web 應用程序時編寫的代碼數量。
Web 應用程序的數據訪問
在 .NET Framework 中,通過 ADO.NET API 執行數據訪問。API 提供一個抽象層來封裝和隱藏直接訪問數據庫的細節,這些細節有時是很雜亂的。ASP.NET 2.0 Web 應用程序通過提供的一些服務在 ADO.NET 上生成,這些服務用于自動生成與各種類型數據的連接,將用戶控件與數據綁定,減少開發數據識別的 Web 應用程序所需的代碼數量。
數據訪問體系結構
對于 .NET Framework 中的 Web 應用程序,數據訪問依賴于兩個獨立的體系結構層。第一層由執行數據訪問所需的框架組件組成。第二層由為程序員提供數據訪問功能的 API 和控件組成。從實踐的觀點看,只需了解能否為特定數據源找到匹配的數據提供程序。
數據訪問涉及四個主要的組件:Web 應用程序 (ASP.NET)、數據層 (ADO.NET)、數據提供程序,以及真正的數據源。這些組件之間的關系構成了所有數據識別 Web 應用程序的基礎結構。

圖 1. 組件體系結構
數據存儲
數據存儲始于堆棧底部,提供了整個數據訪問體系結構的基礎。通過 ADO.NET 2.0、ASP.NET 2.0 的新增控件,Web 應用程序能夠訪問多種數據存儲中的數據,包括關系數據庫、XML 文件、Web 服務、平面文件,或諸如 Microsoft Excel 這樣的電子數據表程序中的數據。實際上,真正的數據源與讀取和操作數據所使用的機制關系不大。
數據提供程序
由于具有提供程序模型,ADO.NET 使用一組類和命令與不同的數據源進行交互。提供程序通過定義的一組接口和類掛鉤來提供對一個特定數據源的存儲和檢索功能。這種模型的靈活性使開發人員只需編寫一組數據訪問代碼(使用 ADO.NET)就能夠訪問多種類型的數據。
在 ASP.NET 2.0 中,除了基本的數據訪問之外,提供程序模型實際上還用于多種不同的任務。例如,使用新增的個性化功能存儲用戶數據時依賴于幾類提供程序。因此,實際的提供程序結構是功能依賴的。一個成員提供程序的用途與數據訪問提供程序的用途不同。
下表顯示組成 ADO.NET 數據提供程序的四個核心對象:
提供程序模型明確地分離了各種使用用途。ASP.NET 開發人員能夠集中精力構建功能性的、應用人類工程學的用戶界面,而后端開發人員則能夠通過現有的企業級數據存儲實現復雜的集成。使用 ASP.NET 2.0 的提供程序模型開發 Web 應用程序是一個極好的選擇。
ADO.NET API
ADO.NET API 定義的抽象層使所有的數據源看起來都是相同的。不論何種數據源,提取信息的過程都涉及相同的關鍵類和步驟。我們將在下一部分詳細介紹 ADO.NET 的處理過程。
Web 應用程序層
ASP.NET 在棧頂提供一系列控件,這些控件的設計意圖是為減少開發的數據訪問代碼數量。例如,開發人員能使用數據源向導自動創建和配置一個數據源,使用這個數據源發布查詢和檢索結果。此外,不同的控件能夠綁定到一個數據源,因此,控件能夠依據從數據源檢索到的信息,自動設置控件的外觀和內容。
這些控件具有各種形狀和大小,包括網格、樹、菜單和列表。數據綁定控件通過它的 DataSourceID 屬性連接到一個數據源,此屬性在設計時或運行時聲明。
數據源控件通過提供程序(例如 ADO.NET 中的那些提供程序)綁定到下層的數據存儲。使用數據源控件的好處是能夠在頁面中聲明性地表示出來。此外,能夠直接使用諸如分頁、排序和更新操作等功能,而無需編寫一行代碼。
數據訪問 API
第二個體系結構層提供使用提供程序、ADO.NET 和 ASP.NET 控件的通用機制。這個體系結構涉及一些通用任務和過程。然而,從開發人員的視角來看,使用 ASP.NET 2.0 提供的各種數據綁定控件和數據源控件無需編寫代碼來支持這些過程。
連接和命令
ADO.NET 包含的 .NET Framework 數據提供程序用于連接一個數據庫,執行命令和檢索結果。在 ADO.NET 中,使用 Connection 對象連接一個指定的數據源。例如,在 SQL Server 2000 中,能夠使用 SQLConnection 對象連接一個數據庫,如以下代碼所示。
連接到數據源后,能夠使用 Command 對象執行命令和返回結果。Command 對象通過 Command 的構造函數創建,這個構造函數接收一個 SQL 語句或 SQL 查詢。一旦創建了 Command,就能使用 CommandText 屬性修改 SQL 語句。
Visual Basic] Dim catCMD As SqlCommand = _ New SqlCommand("SELECT CategoryID, CategoryName FROM Categories", nwindConn) [C#] SqlCommand catCMD = new SqlCommand("SELECT CategoryID, CategoryName FROM Categories", nwindConn);
您可將一條命令認為是等同于一個特定的 SQL 調用,該調用綁定到一個特定的數據庫。一條命令只能用于 CommandText 字段中定義的特定調用。
Command 對象提供了一些不同的 Execute 方法來啟動存儲過程,執行查詢或者執行非查詢語句,例如更新或插入:
當然,您需要依據初始化 Command 對象時創建的命令來選擇正確的 Execute 方法。
ExecuteReader 方法將任何結果都返回到 DataReader 對象。DataReader 對象是查詢數據庫返回的一個關聯的、只進的只讀數據流。執行查詢時,第一行返回到 DataReader 中。數據流保持到數據庫的連接,然后返回下一條記錄。DataReader 從數據庫中讀取行數據時,每行的列值都被讀取和計算,但是不能被編輯。
DataAdapter 和 DataSet
雖然連接數據庫的應用程序使用 DataReader 就已足夠,但是,DataReader 不能很好地支持數據庫訪問的斷開連接模型。而 DataAdapter 和 DataSet 類則滿足了這一需求。
DataSet 是 ADO.NET 斷開連接體系結構中主要的數據存儲工具。填充 DataSet 時,并非通過 Connection 對象將 DataSet 直接連接到數據庫。您必須創建一個 DataAdapter 來填充 DataSet。DataAdapter 連接數據庫,執行查詢并填充 DataSet。當 DataAdapter 調用 Fill 或 Update 方法時,在后臺完成所有的數據傳輸。每個 .NET Framework 的數據提供程序都有一個 DataAdapter 對象。
一個 DataSet 代表一組完整的數據,包括表格、約束條件和表關系。DataSet 能夠存儲代碼創建的本地數據,也能存儲來自多個數據源的數據,并斷開到數據庫的連接。
DataAdapter 能控制與現有數據源的交互。DataAdapter 也能將對 DataSet 的變更傳輸回數據源中。下列代碼說明使用 DataSet 典型情況。
在以上代碼中:
一旦創建了 DataSet,就能夠將它綁定到任何數據識別的控件,方法是通過控件的 DataSource 屬性和 DataBind() 方法。不幸的是,如果數據發生更改,您不得不再次調用 DataBind(),將控件重新綁定到數據集。因此,ASP.NET 1.x 開發人員不得不考慮調用綁定方法的精確時間和位置。開發出正確的同步方法和同步事件是相當困難的。
由于存在數據源的概念,ASP.NET 2.0 極大地簡化了創建、綁定 DataSet 以及保持數據同步的全部過程。
ASP.NET 2.0
ASP.NET 2.0 從幾個方面極大地改進了基本模型。最突出的一方面是,通過 DataSource 隱藏了創建 SQLCommand、生成 DataAdapter 和填充 DataSet 的過程,或者由數據綁定向導自動配置這個過程。
Configure DataSource Wizard 生成的代碼能夠連接數據源(數據庫、平面文件、XML、對象),創建查詢,并允許開發人員以簡單的幾個步驟指定參數。
一旦創建了數據源,下一步就是將數據源連接到一個控件。這里的“連接”就是所謂的數據綁定。從數據源提取的值能夠連接到控件屬性或作為表格、列表或網格中的值使用,這些操作都無需編寫任何代碼。
ASP.NET 數據控件
ASP.NET 1.1 是為使用 ADO.NET API 和簡化數據訪問而設計的。ADO.NET 2.0 通過新增的一組控件和向導進一步簡化了數據訪問過程和編寫代碼的數量,這些控件和向導是針對數據識別的應用程序,為提高開發速度和簡化開發過程而設計的。
DataSource 控件
新的 ASP.NET 2.0 數據訪問系統的核心是 DataSource 控件。一個 DataSource 控件代表一個備份數據存儲(數據庫、對象、xml、消息隊列等),能夠在 Web 頁面上聲明性地表示出來。頁面并不顯示 DataSource,但是它確實可以為任何數據綁定的 UI 控件提供數據訪問。為了支持 DataSource 并使用自動數據綁定,利用一個事件模型以便在更改數據時通知控件,各種 UI 控件都進行了重新設計。此外,數據源還提供了包括排序、分頁、更新、刪除和插入在內的功能,執行這些功能無需任何附加代碼。
最終,所有 DataSource 控件公開一個公共接口,因此,數據綁定控件無需了解連接細節(即連接到一個數據庫還是一個 XML 文件)。每個 DataSource 還公開了特定于數據源的屬性,因而對開發人員而言更為直觀。例如,SqlDataSource 公開了 ConnectionString 和 SelectCommand 屬性,而 XMLDataSource 則公開了定義源文件和任何架構的屬性。在底層,所有數據源都創建特定于提供程序的基礎 ADO.NET 對象,該對象是檢索數據所需的。
創建一個 DataSource
在ASP.NET 2.0 中,DataSource 的子類是新增的數據控件中功能最強大的。它們提供了到數據庫、XML 文件或其他數據源的聲明性配置連接。使用控件從數據源檢索和更新數據無需添加任何自定義代碼。Configure DataSource Wizards 的圖形化界面允許程序員定義相應的細節來配置數據源,幾個簡單的步驟就可以完成。ASP.NET 2.0 自動生成代碼來連接資源,如果合適,創建基于參數的查詢。自動生成的代碼結果存儲在一個 .ASPX 文件中。例如,在 .ASPX 文件中存儲的 SQLDataSource 代碼包含連接字符串的屬性和 SQL 語句的屬性。
當然,開發人員能夠根據需要修改這些代碼。例如,可以將提供程序名移動到 web.config 文件或其他中心位置。
數據源類型
ASP.NET 2.0 提供了幾個獨特的數據源對象,用于為數據綁定控件構造一個公共接口框架。數據源的對象用于操作不同的基礎結構(從數據庫、內存中的對象到 XML 文件),為控件提供抽象數據操作功能。
AccessDataSource
如果在應用程序中使用 Microsoft Access 數據庫,則能夠通過 System.Web.UI.WebControls.AccessDataSource 執行插入、更新和刪除數據的操作。Access 數據庫是提供基本關系存儲的最小數據庫。因為使用起來既簡單又方便,所以許多小型的 Web 站點通過 Access 形成數據存儲層。雖然 Access 不提供像 SQL Server 這樣的關系數據庫的所有功能,但是其簡單性和易用性使 Access 非常適合應用于原型開發和快速應用程序開發 (RAD)。
SqlDataSource
為了提供一個更加健壯的數據庫,綜合利用 Microsoft SQL Server 提供的廣泛功能,ASP.NET 2.0 提供了 SQLDataSource。SQLDataSource 的配置比 AccessDataSource 的更為復雜,SQLDataSource 用于企業級應用程序,這些應用程序需要一個真正的數據庫管理系統 (DBMS) 所擁有的功能。
ObjectDataSource
System.Web.UI.WebControls.ObjectDataSource 用于實現一個數據訪問層,從而提供更好的封裝和抽象。ObjectDataSource 控件支持綁定到一個特定的數據層,而非綁定到一個數據庫,其綁定方式與使用其他控件綁定數據庫的方式相同。ObjectDataSource 控件能夠綁定到任何一個方法,該方法返回一個 DataSet 對象或 IEnumerable 對象(例如,一個 DataReader 或類集合)。
ObjectDataSource 控件使用 Web 服務代理的方式與使用數據訪問層的方式完全相同。換句話說,ObjectDataSource 處理設計正確的 Web 服務與處理一個關系數據庫的方式相同。
DataSetDataSource
System.Web.UI.WebControls.DataSetDataSource 控件允許使用 XML 列表數據。列表數據以行和列排列。
要使用數據,只需設置 DataFile 屬性,使其指向 XML 文件。
數據源能夠連接到任何列表控件,例如 DataGrid。
XmlDataSource
XML 數據通常用于表示半結構化或層次化數據。使用 XML 文檔作為數據源,可以從其他資源(例如,其他公司或現有應用程序)接收 XML 文檔,并將 XML 數據格式化,以便與應用程序兼容。
要配置一個 System.Web.UI.WebControls.XmlDataSource,必須指定 XML 文件的路徑,如果 XML 需要傳輸數據,則還需指定 XSLT 樣式表路徑或 XPath 查詢路徑(可選)。
XMLDataSource 特別適用于擁有層次結構的控件,例如,樹視圖或數據列表。
以上兩個列表說明了如何聲明性地配置一個 XmlDataSource 和一個 TreeView 控件,使之呈現如圖 2 所示的 XML 層次結構。

圖 2. TreeView 控件
TreeView 控件自動生成標記來創建一個用戶界面,支持用戶單擊父實體時展開節點。TreeView 控件通過 XMLDataSource 綁定到 fruits.xml 文件。
SiteMapDataSource
System.Web.UI.WebControls.SiteMapDataSource 控件能夠在邏輯上(而非物理上)實現 Web 站點的導航。通過生成一個邏輯結構,導航不受文件物理地址變動的影響。即使頁面物理位置改變,您也不必更改應用程序的導航結構。
要使用 SiteMapDataSource,第一步是創建一個 XML 文件來映射 SiteMapNode 元素的層次結構,從而指定站點的導航結構。您可以將 XML 文件保存為 app.sitemap。
當您在應用程序中使用 SiteMapDataSource 時,它將查找指定的 app.sitemap 文件。然后,SiteMapDataSource 連接到導航控件,實現邏輯導航。

圖 3. Home-> Articles-> Article 2 頁面的詳細路經跟蹤
數據綁定
一旦創建了一個數據源,接下來是將數據源連接到一個控件。這里的“連接”就是所謂的數據綁定。ASP.NET v1.x 提供了一些數據綁定控件,例如 DataGrid、DataList 和 DropDownList 等。ASP.NET 2.0 對改進數據綁定控件的概念作出了幾個重要的創新:
在 ASP.NET v1.x 中,頁面開發人員需要手動處理數據綁定控件事件,編寫代碼來執行這些操作。而在 ASP.NET 2.0 中,數據綁定控件直接使用數據源的功能。當然,頁面開發人員仍能處理適當的事件以自定義這些操作的處理;例如,驗證輸入。
ASP.NET 2.0 支持多種不同控件豐富的數據綁定。例如,能夠將一個 XML 數據源綁定到 <ASP:DropDownList>、<ASP:DataList>、<ASP: GridView> 以及許多其他的數據控件。
ASP.NET 2.0 中的數據綁定
傳統的應用程序需要編寫代碼來綁定數據。例如,要在傳統的 ASP 中填充下拉列表,或對頁面中的值進行硬編碼(如下所示),或編寫代碼來連接數據庫,檢索數據,再填充下拉列表。如果手動填充下拉列表,則每次更新數據時,必須更改代碼(手動)。
如果通過訪問數據庫表的方式填充列表,則不僅需要編寫代碼來檢索信息,而且每次加載頁面時,應用程序都需要訪問數據庫,或在應用程序級或會話級緩存信息。
另一方面,ASP.NET 1.1 允許將控件綁定到數據庫表和 XML 文檔。但是,在 ASP.NET 1.1 中,如果要綁定到一個 XML 數據源,需要將 XML 轉換為 DataSet(本文前面作過概述)。一旦獲得轉換后的 DataSet,只要將 DataSet 綁定到控件上即可。
但是,每此更新 XML 數據源,必須重新將控件綁定到一個新的 DataSet,這是因為 DataSet 不能動態地連接到源文件。
在ASP.NET 2.0中綁定控件
ASP.NET 2.0 允許將下拉列表綁定到 XML 數據源或數據庫,而無需編寫任何代碼。如果更新基礎數據,它能夠確保緩存值自動刷新。
要綁定控件,首先需要創建一個數據源。可以手動編寫數據源定義代碼,或使用 Configure Data Source Wizard。

圖 4a.配置 ObjectDataSource 向導

圖 4b.配置 XmlDataSource 向導
XMLDataSource 配置向導在 Web.config 文件中生成了下面的代碼。
一旦建立了數據源,就能夠將數據綁定到控件。下列代碼顯示如何將 XML 數據源綁定到下拉列表控件。
請注意,ASP.NET 1.x 和 ASP.NET 2.0 中數據綁定的主要區別在于提供程序模型是否自動同步發生了更改的數據。換句話說,由于在數據源中置入了一個事件模型,如果修改支持數據源的數據,則自動更新綁定控件。
數據綁定控件
ASP.NET 2.0 引入了幾個用于顯示數據的新控件。這些新控件提供了一些比 ASP.NET 1.1 的 DataGrid 控件更優越的增強功能。
GridView 控件
ASP.NET 1.1 的 DataGrid 控件功能強大,使用靈活,允許顯示結構化數據,無需編寫大量代碼。但是,如果要操作 DataGrid 的內容(例如,編輯或對返回行進行排序),需要編寫適量的代碼,自定義控件并提供這些行為。
GridView 與 DataGrid 控件相似;但是,您也能夠通過向導一步步聲明性地配置控件,啟用像編輯和顯示多頁行數據這樣的通用任務。
配置 GridView
為了說明實現上述功能多么輕松,請思考這個例子:根據下拉列表的選擇項顯示查詢結果。只需將 GridView 控件拖放到頁面上,配置控件以根據下拉列表的選擇項自動顯示結果。

圖 5. 將 GridView 綁定到 DropDown 列表
要配置 GridView 控件,您必須通過 Configure Data Source Wizard 將它綁定到數據源。圖 6 還顯示 DataGrid 對象提供的 Enable Paging、Enable Sorting 和 Enable Selection 選項。
在 Configure Data Source 窗口中,選擇適當的表格,然后選擇所需的元素。窗口底部顯示自動生成的 SQL 查詢語句。

圖 6. 編輯 SQL 數據源
下一步,單擊 WHERE 按鈕,配置 GridView 中顯示的記錄的條件;在下面的窗口中選擇 patientID 列,設置操作符和源選項。當源選項設置為 Control 時,當前頁面中的所有控件將自動填充到 Parameter 屬性的 Control ID 字段中。從列表中選擇想要連接的控件。配置好參數和默認值(如果需要)后,單擊 Add 按鈕,再單擊 OK 按鈕進行確認。

圖 7. 查詢編輯器對話框
生成的 select 語句可通過 Configure DataSource 窗口查看。
在 ASP 和 ASP.NET 應用程序中,必須編寫代碼完成所有這些過程,還要編寫 HTML 代碼來顯示格式化的結果。新的 GridView 控件生成了以下結果,沒有附加任何代碼(請注意,Edit 和 Delete 鏈接是自動可見的,并注意生成的 SQL):

圖 8. 綁定到下拉列表的 GridView 控件顯示的結果
DetailsView 控件
DetailsView 控件與 GridView 控件相似,它使用完全相同的安裝機制。GridView 控件在一頁顯示多條記錄,而 DetailsView 控件一次只顯示一條記錄。

圖 9. 在 DetailsView 控件中顯示一條記錄
因此,DetailsView 控件與 GridView 控件形成了很好的互補。將 DetailsView 連接到 GridView 可以更好地控制更新個別項目或插入新項目的方式和時機。
FormView 控件
使用上述配置步驟,我們還能夠為 ASP.NET 的開發配置另一個新控件 — FormView 控件。FormView 控件支持非常靈活的 UI 布局。下面的示例顯示使用 FormView 控件查看單個數據庫記錄。

圖 10. FormView ItemTemplate 輸出
像 ItemTemplate 和 EditItemTemplate 這樣不同的模板用于查看和修改數據庫記錄,無需任何自定義代碼。

圖 11. FormView EditTemplate 輸出
新增的 ASP.NET 2.0 數據功能
除了前面章節介紹的新控件,ASP.NET 2.0 還提供幾個與數據訪問有關的新功能,這些功能有助于提高數據驅動應用程序的性能和安全性。
性能
Web 應用程序的性能通常可以通過兩種機制來改進。首先,Web 應用程序層能夠緩存盡可能多的數據,減少了不必要的數據層調用。其次,Web 應用程序可以減少調用數據層的次數和大小。
數據源緩存
SQLDataSource 和 ObjectDataSource 支持數據層緩存。通過設置數據源對象的一些屬性,程序員不用開發任何自定義代碼,即可使用緩存 api。數據源對象將自動管理底層存儲機制的一致性。
SQL 緩存依賴關系
對大多數數據驅動的 Web 站點來說,緩存數據是復雜的任務。Web 站點需要使用緩存來提高性能,但是更新數據的需求也很迫切。ASP.NET 1.x 能將頁面緩存一段時間,并通過輸入參數(QUERYSTRING 或 POST 參數)進行組織。
以上代碼根據變量 ProdID (產品 id)在內存中緩存頁面一小時。
如果在應用程序的其他地方更新了下層數據,緩存數據將出現問題。例如,考慮將一個產品目錄頁面通過產品 ID 進行緩存。如果從一個管理站點更新產品信息(例如,可用數量或價格),過期數據仍保留在緩存中,并顯示給客戶。在 ASP.NET 1.x 中,必須等待緩存失效,或使用 Response.RemoveOutputCacheItem 強制緩存失效。
ASP.NET 2.0 通過實現表格級 SQL 通知來支持數據庫緩存依賴關系。更改數據時,一個表格級依賴關系通知頁面。下面的代碼將產品頁面緩存了一小時,但是向數據庫表添加了一個依賴關系。
向 Products 表格添加新的 SQLDependency 屬性后,不論表格發生任何更改,緩存過的頁面都將失效。SQLDependency 屬性必須引用在 web.config 文件中配置的 Microsoft SQL Server DataSource。DataSource 標識了使依賴關系通知有效的數據庫連接和參數。
自定義 SQL 依賴關系
雖然默認情況下 SQLDependency 類只支持 Microsoft SQL Server,但是您能夠通過 machine.config 和 web.config 文件替代和重新配置類。這個功能允許您創建自定義的 SQLDependency 類,為任何 DataSource(包括 Oracle、Sybase 或其他任何數據庫)提供相似的功能。
數據源緩存
在 ASP.NET 2.0 中,緩存數據的另一個方法是使用直接置入數據源的緩存機制。例如,SQLDataSource 和 ObjectDataSource 類都支持通過 EnableCaching 屬性直接緩存。只需將該屬性設置為 true,數據源將自動緩存從數據存儲提取的數據。緩存將根據 CacheDuration 屬性設定的時間或通過類似于頁面級指令的 SQLCacheDependency 失效。由于在數據源控件中置入了這些功能,無需編寫任何代碼,您就能快速、輕松地實現緩存。
改進的 DataSet 遠程處理支持
對 ASP.NET 1.1 最多的抱怨是:由于通常要將 DataSet 序列化為 XML,因此通過 .NET 遠程處理發送 DataSet 比發送其他序列化二進制表示形式慢。ASP.NET 2.0 將 DataSet 作為二進制序列化表示形式進行傳輸,以幫助減少 DataSet 的傳輸大小和傳遞信息所需的傳輸時間。
安全性
ASP.NET 2.0 提供的一項服務能夠加密配置文件的任何部分。通過加密,您能夠更安全地存儲應用程序內的信息。例如,可以加密 Web.config 文件的 ConnectionString 部分來保護所有的敏感信息。配置加密允許您安全地存儲像連接字符串這樣的信息。
加密配置信息時,您可以使用政府標準加密算法,例如三重 DES。因為加密數據存儲在配置文件中,所以應用程序不依賴于注冊表。
小結
ASP.NET 2.0 致力于幫助您靈活地控制數據,通過在新增的數據控件中封裝功能,減少訪問數據和顯示數據所需的代碼數量。新的數據訪問模型和控件減少的數據訪問代碼多達 70%。現在,傳統的 ASP 或 ASP.NET 1.1 應用程序中需要手動設計的許多功能都已內置到新的數據控件中了。數據訪問的新體系結構也是可擴展的,是為訪問多種不同的數據源數據而設計的,這些數據源包括數據庫、XML 文件、平面文件、數據流等等。作為一名企業級開發人員,您能夠利用新的體系結構連接任何后端數據源,而仍然使用一個簡單的前端接口。
數據訪問一直是開發 Web 應用程序的一個關鍵問題。幾乎每個商業應用程序都需要數據驅動的 Web 頁面。由于數據訪問如此普遍,開發人員不斷地為簡單的數據庫任務重新生成復雜的代碼就顯得毫無意義了。開發人員需要從格式各異的不同數據源中快速訪問數據。幸運的是,ASP.NET 2.0 中新增的數據訪問控件和 ADO.NET 2.0 解決了這一問題。
對于傳統的 ASP 和 ASP.NET 1.1 應用程序而言,開發人員不得不創建代碼訪問和更新數據庫,將檢索到的數據轉換為瀏覽器識別的 HTML 格式。盡管 Visual Studio .NET 的向導可以幫助完成這個任務,但是要完成諸如分頁和排序這樣的高級功能,仍需要在后端代碼和前端顯示之間進行復雜的同步。通常,這樣的代碼難以維護和同步,特別是在數據庫發生更改或需要在頁面上顯示附加數據的時候。此外,作為數據存儲,XML 需要添加大量混有數據訪問邏輯的代碼。
為了提高開發人員的開發效率和 Web 應用程序的性能,ASP.NET 2.0 通過新增的數據控件中封裝的功能,更加靈活地控制數據,從而減少訪問和顯示數據所需的代碼。從傳統的數據庫到 XML 數據存儲,各種各樣的數據源都能連接到這些控件。所有數據源都以相似的格式進行處理,大大地降低了開發數據驅動的應用程序的復雜性。ASP.NET 2.0 需要進行廣泛的體系結構改進,以便從內部支持這些功能。新增的數據源對象通過業界認可的最佳方法增加了一個非常可靠的基礎結構。現在,大多數復雜的應用程序都可以利用 ASP.NET 2.0 提供的數據訪問工具。從體系結構和機制上限制 ASP.NET 1.x 執行的綁定和緩存問題,在 ASP.NET 2.0 中都得以解決了。
如果您是一位 ASP 開發人員,那么您會通過這篇白皮書了解到 ASP.NET 2.0 新增的數據訪問功能和 ADO.NET 2.0 的數據訪問模型。如果您是一位 ASP.NET 1.1 的開發人員,那么這篇白皮書概括的 ADO.NET 新增的改進功能和數據訪問模型,以及介紹的如何使用 ASP.NET 2.0 新增的數據訪問控件將幫助您減少開發數據驅動 Web 應用程序時編寫的代碼數量。
Web 應用程序的數據訪問
在 .NET Framework 中,通過 ADO.NET API 執行數據訪問。API 提供一個抽象層來封裝和隱藏直接訪問數據庫的細節,這些細節有時是很雜亂的。ASP.NET 2.0 Web 應用程序通過提供的一些服務在 ADO.NET 上生成,這些服務用于自動生成與各種類型數據的連接,將用戶控件與數據綁定,減少開發數據識別的 Web 應用程序所需的代碼數量。
數據訪問體系結構
對于 .NET Framework 中的 Web 應用程序,數據訪問依賴于兩個獨立的體系結構層。第一層由執行數據訪問所需的框架組件組成。第二層由為程序員提供數據訪問功能的 API 和控件組成。從實踐的觀點看,只需了解能否為特定數據源找到匹配的數據提供程序。
數據訪問涉及四個主要的組件:Web 應用程序 (ASP.NET)、數據層 (ADO.NET)、數據提供程序,以及真正的數據源。這些組件之間的關系構成了所有數據識別 Web 應用程序的基礎結構。

圖 1. 組件體系結構
數據存儲
數據存儲始于堆棧底部,提供了整個數據訪問體系結構的基礎。通過 ADO.NET 2.0、ASP.NET 2.0 的新增控件,Web 應用程序能夠訪問多種數據存儲中的數據,包括關系數據庫、XML 文件、Web 服務、平面文件,或諸如 Microsoft Excel 這樣的電子數據表程序中的數據。實際上,真正的數據源與讀取和操作數據所使用的機制關系不大。
數據提供程序
由于具有提供程序模型,ADO.NET 使用一組類和命令與不同的數據源進行交互。提供程序通過定義的一組接口和類掛鉤來提供對一個特定數據源的存儲和檢索功能。這種模型的靈活性使開發人員只需編寫一組數據訪問代碼(使用 ADO.NET)就能夠訪問多種類型的數據。
在 ASP.NET 2.0 中,除了基本的數據訪問之外,提供程序模型實際上還用于多種不同的任務。例如,使用新增的個性化功能存儲用戶數據時依賴于幾類提供程序。因此,實際的提供程序結構是功能依賴的。一個成員提供程序的用途與數據訪問提供程序的用途不同。
下表顯示組成 ADO.NET 數據提供程序的四個核心對象:
表 1. 一個 ADO.NET 數據提供程序的核心對象 | |
對象 | 描述 |
Connection | 建立到指定資源的連接 |
Command | 對一個數據源執行命令。公開 Parameters,在 Connection 的 Transaction 范圍內執行。 |
DataReader | 從一個數據源讀取只進的只讀數據流。 |
DataAdapter | 填充一個 DataSet,解析數據源的更新。 |
提供程序模型明確地分離了各種使用用途。ASP.NET 開發人員能夠集中精力構建功能性的、應用人類工程學的用戶界面,而后端開發人員則能夠通過現有的企業級數據存儲實現復雜的集成。使用 ASP.NET 2.0 的提供程序模型開發 Web 應用程序是一個極好的選擇。
ADO.NET API
ADO.NET API 定義的抽象層使所有的數據源看起來都是相同的。不論何種數據源,提取信息的過程都涉及相同的關鍵類和步驟。我們將在下一部分詳細介紹 ADO.NET 的處理過程。
Web 應用程序層
ASP.NET 在棧頂提供一系列控件,這些控件的設計意圖是為減少開發的數據訪問代碼數量。例如,開發人員能使用數據源向導自動創建和配置一個數據源,使用這個數據源發布查詢和檢索結果。此外,不同的控件能夠綁定到一個數據源,因此,控件能夠依據從數據源檢索到的信息,自動設置控件的外觀和內容。
這些控件具有各種形狀和大小,包括網格、樹、菜單和列表。數據綁定控件通過它的 DataSourceID 屬性連接到一個數據源,此屬性在設計時或運行時聲明。
數據源控件通過提供程序(例如 ADO.NET 中的那些提供程序)綁定到下層的數據存儲。使用數據源控件的好處是能夠在頁面中聲明性地表示出來。此外,能夠直接使用諸如分頁、排序和更新操作等功能,而無需編寫一行代碼。
數據訪問 API
第二個體系結構層提供使用提供程序、ADO.NET 和 ASP.NET 控件的通用機制。這個體系結構涉及一些通用任務和過程。然而,從開發人員的視角來看,使用 ASP.NET 2.0 提供的各種數據綁定控件和數據源控件無需編寫代碼來支持這些過程。
連接和命令
ADO.NET 包含的 .NET Framework 數據提供程序用于連接一個數據庫,執行命令和檢索結果。在 ADO.NET 中,使用 Connection 對象連接一個指定的數據源。例如,在 SQL Server 2000 中,能夠使用 SQLConnection 對象連接一個數據庫,如以下代碼所示。
[Visual Basic] Dim nwindConn As SqlConnection = _ New SqlConnection("Data Source=localhost;Integrated Security=SSPI;" _ "Initial Catalog=northwind") nwindConn.Open() [C#] SqlConnection nwindConn = new SqlConnection("Data Source=localhost; Integrated Security=SSPI;" "Initial Catalog=northwind"); nwindConn.Open(); |
連接到數據源后,能夠使用 Command 對象執行命令和返回結果。Command 對象通過 Command 的構造函數創建,這個構造函數接收一個 SQL 語句或 SQL 查詢。一旦創建了 Command,就能使用 CommandText 屬性修改 SQL 語句。
Visual Basic] Dim catCMD As SqlCommand = _ New SqlCommand("SELECT CategoryID, CategoryName FROM Categories", nwindConn) [C#] SqlCommand catCMD = new SqlCommand("SELECT CategoryID, CategoryName FROM Categories", nwindConn);
您可將一條命令認為是等同于一個特定的 SQL 調用,該調用綁定到一個特定的數據庫。一條命令只能用于 CommandText 字段中定義的特定調用。
Command 對象提供了一些不同的 Execute 方法來啟動存儲過程,執行查詢或者執行非查詢語句,例如更新或插入:
1. | ExecuteReader 方法 — 將數據作為一個 DataReader 對象返回。用于任何返回數據的 SQL 查詢。 |
2. | ExecuteScalar 方法 — 返回單獨值,例如與特定查詢相匹配的記錄數,或者數據庫功能調用的結果。 |
3. | ExecuteNonQuery 方法 — 執行不返回任何行的命令。典型的例子是存儲過程、插入和更新。 |
當然,您需要依據初始化 Command 對象時創建的命令來選擇正確的 Execute 方法。
ExecuteReader 方法將任何結果都返回到 DataReader 對象。DataReader 對象是查詢數據庫返回的一個關聯的、只進的只讀數據流。執行查詢時,第一行返回到 DataReader 中。數據流保持到數據庫的連接,然后返回下一條記錄。DataReader 從數據庫中讀取行數據時,每行的列值都被讀取和計算,但是不能被編輯。
DataAdapter 和 DataSet
雖然連接數據庫的應用程序使用 DataReader 就已足夠,但是,DataReader 不能很好地支持數據庫訪問的斷開連接模型。而 DataAdapter 和 DataSet 類則滿足了這一需求。
DataSet 是 ADO.NET 斷開連接體系結構中主要的數據存儲工具。填充 DataSet 時,并非通過 Connection 對象將 DataSet 直接連接到數據庫。您必須創建一個 DataAdapter 來填充 DataSet。DataAdapter 連接數據庫,執行查詢并填充 DataSet。當 DataAdapter 調用 Fill 或 Update 方法時,在后臺完成所有的數據傳輸。每個 .NET Framework 的數據提供程序都有一個 DataAdapter 對象。
一個 DataSet 代表一組完整的數據,包括表格、約束條件和表關系。DataSet 能夠存儲代碼創建的本地數據,也能存儲來自多個數據源的數據,并斷開到數據庫的連接。
DataAdapter 能控制與現有數據源的交互。DataAdapter 也能將對 DataSet 的變更傳輸回數據源中。下列代碼說明使用 DataSet 典型情況。
[Visual Basic] Dim nwindConn As SqlConnection = _ New SqlConnection("Data Source=localhost;" & _ "Integrated_Security=SSPI;Initial Catalog=northwind") Dim selectCMD As SqlCommand = _ New SqlCommand("SELECT CustomerID, CompanyName FROM " & _ "Customers", nwindConn) selectCMD.CommandTimeout = 30 Dim custDA As SqlDataAdapter= New SqlDataAdapter custDA.SelectCommand= selectCMD Dim custDS As DataSet= New DataSet custDA.Fill(custDS, "Customers") nwindConn.Close() [C#] SqlConnection nwindConn = new SqlConnection("Data Source=localhost;" + "IntegratedSecurity=SSPI;Initial Catalog=northwind"); SqlCommand selectCMD = new SqlCommand("SELECT CustomerID, CompanyName FROM Customers", nwindConn); selectCMD.CommandTimeout = 30; SqlDataAdaptercustDA = new SqlDataAdapter(); custDA.SelectCommand= selectCMD; nwindConn.Open(); DataSetcustDS = new DataSet(); custDA.Fill(custDS, "Customers"); nwindConn.Close(); |
在以上代碼中:
1. | 創建了一個 SQLConnection 來連接 SQL Server 數據庫。 |
2. | 創建了一個 SQLCommand 來查詢 Customers 表格。 |
3. | 創建了一個 DataAdapter 來執行 SQLCommand 和數據操作的連接部分。 |
4. | 從 DataAdapter 可以創建一個 DataSet。DataSet 是數據操作的斷開連接部分,并且能綁定到 ASP.NET 2.0 的各種 Web 控件。 |
一旦創建了 DataSet,就能夠將它綁定到任何數據識別的控件,方法是通過控件的 DataSource 屬性和 DataBind() 方法。不幸的是,如果數據發生更改,您不得不再次調用 DataBind(),將控件重新綁定到數據集。因此,ASP.NET 1.x 開發人員不得不考慮調用綁定方法的精確時間和位置。開發出正確的同步方法和同步事件是相當困難的。
由于存在數據源的概念,ASP.NET 2.0 極大地簡化了創建、綁定 DataSet 以及保持數據同步的全部過程。
ASP.NET 2.0
ASP.NET 2.0 從幾個方面極大地改進了基本模型。最突出的一方面是,通過 DataSource 隱藏了創建 SQLCommand、生成 DataAdapter 和填充 DataSet 的過程,或者由數據綁定向導自動配置這個過程。
Configure DataSource Wizard 生成的代碼能夠連接數據源(數據庫、平面文件、XML、對象),創建查詢,并允許開發人員以簡單的幾個步驟指定參數。
一旦創建了數據源,下一步就是將數據源連接到一個控件。這里的“連接”就是所謂的數據綁定。從數據源提取的值能夠連接到控件屬性或作為表格、列表或網格中的值使用,這些操作都無需編寫任何代碼。
ASP.NET 數據控件
ASP.NET 1.1 是為使用 ADO.NET API 和簡化數據訪問而設計的。ADO.NET 2.0 通過新增的一組控件和向導進一步簡化了數據訪問過程和編寫代碼的數量,這些控件和向導是針對數據識別的應用程序,為提高開發速度和簡化開發過程而設計的。
DataSource 控件
新的 ASP.NET 2.0 數據訪問系統的核心是 DataSource 控件。一個 DataSource 控件代表一個備份數據存儲(數據庫、對象、xml、消息隊列等),能夠在 Web 頁面上聲明性地表示出來。頁面并不顯示 DataSource,但是它確實可以為任何數據綁定的 UI 控件提供數據訪問。為了支持 DataSource 并使用自動數據綁定,利用一個事件模型以便在更改數據時通知控件,各種 UI 控件都進行了重新設計。此外,數據源還提供了包括排序、分頁、更新、刪除和插入在內的功能,執行這些功能無需任何附加代碼。
最終,所有 DataSource 控件公開一個公共接口,因此,數據綁定控件無需了解連接細節(即連接到一個數據庫還是一個 XML 文件)。每個 DataSource 還公開了特定于數據源的屬性,因而對開發人員而言更為直觀。例如,SqlDataSource 公開了 ConnectionString 和 SelectCommand 屬性,而 XMLDataSource 則公開了定義源文件和任何架構的屬性。在底層,所有數據源都創建特定于提供程序的基礎 ADO.NET 對象,該對象是檢索數據所需的。
創建一個 DataSource
在ASP.NET 2.0 中,DataSource 的子類是新增的數據控件中功能最強大的。它們提供了到數據庫、XML 文件或其他數據源的聲明性配置連接。使用控件從數據源檢索和更新數據無需添加任何自定義代碼。Configure DataSource Wizards 的圖形化界面允許程序員定義相應的細節來配置數據源,幾個簡單的步驟就可以完成。ASP.NET 2.0 自動生成代碼來連接資源,如果合適,創建基于參數的查詢。自動生成的代碼結果存儲在一個 .ASPX 文件中。例如,在 .ASPX 文件中存儲的 SQLDataSource 代碼包含連接字符串的屬性和 SQL 語句的屬性。
<asp:sqldatasource id="SqlDataSource1" runat="server" selectcommand="select customerid, companyname from customers" providername="System.Data.OleDb" connectionstring="Provider=SQLOLEDB.1;Integrated Security=SSPI; Initial Catalog=Northwind; Data Source=localhost; Auto Translate=True; Use Encryption for Data=False> </asp:sqldatasource> |
當然,開發人員能夠根據需要修改這些代碼。例如,可以將提供程序名移動到 web.config 文件或其他中心位置。
數據源類型
ASP.NET 2.0 提供了幾個獨特的數據源對象,用于為數據綁定控件構造一個公共接口框架。數據源的對象用于操作不同的基礎結構(從數據庫、內存中的對象到 XML 文件),為控件提供抽象數據操作功能。
AccessDataSource
如果在應用程序中使用 Microsoft Access 數據庫,則能夠通過 System.Web.UI.WebControls.AccessDataSource 執行插入、更新和刪除數據的操作。Access 數據庫是提供基本關系存儲的最小數據庫。因為使用起來既簡單又方便,所以許多小型的 Web 站點通過 Access 形成數據存儲層。雖然 Access 不提供像 SQL Server 這樣的關系數據庫的所有功能,但是其簡單性和易用性使 Access 非常適合應用于原型開發和快速應用程序開發 (RAD)。
SqlDataSource
為了提供一個更加健壯的數據庫,綜合利用 Microsoft SQL Server 提供的廣泛功能,ASP.NET 2.0 提供了 SQLDataSource。SQLDataSource 的配置比 AccessDataSource 的更為復雜,SQLDataSource 用于企業級應用程序,這些應用程序需要一個真正的數據庫管理系統 (DBMS) 所擁有的功能。
ObjectDataSource
System.Web.UI.WebControls.ObjectDataSource 用于實現一個數據訪問層,從而提供更好的封裝和抽象。ObjectDataSource 控件支持綁定到一個特定的數據層,而非綁定到一個數據庫,其綁定方式與使用其他控件綁定數據庫的方式相同。ObjectDataSource 控件能夠綁定到任何一個方法,該方法返回一個 DataSet 對象或 IEnumerable 對象(例如,一個 DataReader 或類集合)。
<asp:objectdatasource id="ObjectDataSource" runat="server" typename="DAL.Customers" selectmethod="GetOrders"> </asp:objectdatasource> |
ObjectDataSource 控件使用 Web 服務代理的方式與使用數據訪問層的方式完全相同。換句話說,ObjectDataSource 處理設計正確的 Web 服務與處理一個關系數據庫的方式相同。
DataSetDataSource
System.Web.UI.WebControls.DataSetDataSource 控件允許使用 XML 列表數據。列表數據以行和列排列。
<?xml version="1.0"?> <collection> <book> <title>cosmos</title> <author>carl sagan</author> <publisher>ballantine books</publisher> </book> <book> <title>catwings</title> <author>ursula k. le guin</author> <publisher>scholastic</publisher> </book> </collection> |
要使用數據,只需設置 DataFile 屬性,使其指向 XML 文件。
<asp:datasetdatasource id="Datasetdatasource1" runat="server" datafile="collection.xml" /> |
數據源能夠連接到任何列表控件,例如 DataGrid。
XmlDataSource
XML 數據通常用于表示半結構化或層次化數據。使用 XML 文檔作為數據源,可以從其他資源(例如,其他公司或現有應用程序)接收 XML 文檔,并將 XML 數據格式化,以便與應用程序兼容。
要配置一個 System.Web.UI.WebControls.XmlDataSource,必須指定 XML 文件的路徑,如果 XML 需要傳輸數據,則還需指定 XSLT 樣式表路徑或 XPath 查詢路徑(可選)。
<asp:XmlDataSource ID="XmlDataSource1" Runat="server" DataFile="'/xml/fruits.xml"> </asp:XmlDataSource> |
XMLDataSource 特別適用于擁有層次結構的控件,例如,樹視圖或數據列表。
<asp:TreeView ID="TreeView1" Runat="server" DataSourceID="XmlDataSource1" ShowLines="True"> </asp:TreeView> |
以上兩個列表說明了如何聲明性地配置一個 XmlDataSource 和一個 TreeView 控件,使之呈現如圖 2 所示的 XML 層次結構。

圖 2. TreeView 控件
TreeView 控件自動生成標記來創建一個用戶界面,支持用戶單擊父實體時展開節點。TreeView 控件通過 XMLDataSource 綁定到 fruits.xml 文件。
SiteMapDataSource
System.Web.UI.WebControls.SiteMapDataSource 控件能夠在邏輯上(而非物理上)實現 Web 站點的導航。通過生成一個邏輯結構,導航不受文件物理地址變動的影響。即使頁面物理位置改變,您也不必更改應用程序的導航結構。
要使用 SiteMapDataSource,第一步是創建一個 XML 文件來映射 SiteMapNode 元素的層次結構,從而指定站點的導航結構。您可以將 XML 文件保存為 app.sitemap。
當您在應用程序中使用 SiteMapDataSource 時,它將查找指定的 app.sitemap 文件。然后,SiteMapDataSource 連接到導航控件,實現邏輯導航。

圖 3. Home-> Articles-> Article 2 頁面的詳細路經跟蹤
數據綁定
一旦創建了一個數據源,接下來是將數據源連接到一個控件。這里的“連接”就是所謂的數據綁定。ASP.NET v1.x 提供了一些數據綁定控件,例如 DataGrid、DataList 和 DropDownList 等。ASP.NET 2.0 對改進數據綁定控件的概念作出了幾個重要的創新:
1. | 現在,當數據綁定控件綁定到一個數據源控件(通過 DataSourceID 屬性)時,能夠自動綁定本身。這使頁面開發人員無需了解頁面的生存周期,并且不必在此時顯式調用 DataBind()。數據綁定控件能夠自動完成這些工作,甚至能偵聽數據源的更改事件。 |
2. | ASP.NET 2.0 引入了新的數據綁定控件,這些控件能自動使用數據源的功能,例如排序、分頁、更新、插入和刪除。 |
在 ASP.NET v1.x 中,頁面開發人員需要手動處理數據綁定控件事件,編寫代碼來執行這些操作。而在 ASP.NET 2.0 中,數據綁定控件直接使用數據源的功能。當然,頁面開發人員仍能處理適當的事件以自定義這些操作的處理;例如,驗證輸入。
ASP.NET 2.0 支持多種不同控件豐富的數據綁定。例如,能夠將一個 XML 數據源綁定到 <ASP:DropDownList>、<ASP:DataList>、<ASP: GridView> 以及許多其他的數據控件。
ASP.NET 2.0 中的數據綁定
傳統的應用程序需要編寫代碼來綁定數據。例如,要在傳統的 ASP 中填充下拉列表,或對頁面中的值進行硬編碼(如下所示),或編寫代碼來連接數據庫,檢索數據,再填充下拉列表。如果手動填充下拉列表,則每次更新數據時,必須更改代碼(手動)。
<select size="1" name="dropdown_menu"> <option value="1" >test_data1</option> <option value="2">test_data2</option> <option value="3">test_data3</option> <option value="4">test_data4</option> </select> |
如果通過訪問數據庫表的方式填充列表,則不僅需要編寫代碼來檢索信息,而且每次加載頁面時,應用程序都需要訪問數據庫,或在應用程序級或會話級緩存信息。
另一方面,ASP.NET 1.1 允許將控件綁定到數據庫表和 XML 文檔。但是,在 ASP.NET 1.1 中,如果要綁定到一個 XML 數據源,需要將 XML 轉換為 DataSet(本文前面作過概述)。一旦獲得轉換后的 DataSet,只要將 DataSet 綁定到控件上即可。
//C# code listbox.DataSource= dataset.Tables[0]; listbox.DataTextField = "Name"; listbox.DataValueField = "ID"; listbox.DataBind() //VB Code listbox.DataSource= dataset.Tables(0) listbox.DataTextField = "Name" listbox.DataValueField = "ID" listbox.DataBind() |
但是,每此更新 XML 數據源,必須重新將控件綁定到一個新的 DataSet,這是因為 DataSet 不能動態地連接到源文件。
在ASP.NET 2.0中綁定控件
ASP.NET 2.0 允許將下拉列表綁定到 XML 數據源或數據庫,而無需編寫任何代碼。如果更新基礎數據,它能夠確保緩存值自動刷新。
要綁定控件,首先需要創建一個數據源。可以手動編寫數據源定義代碼,或使用 Configure Data Source Wizard。

圖 4a.配置 ObjectDataSource 向導

圖 4b.配置 XmlDataSource 向導
XMLDataSource 配置向導在 Web.config 文件中生成了下面的代碼。
<asp:xmldatasource id="XmlDataSource1" datafile="msdn.xml" xpath="rss/channel/item" runat="server" /> |
一旦建立了數據源,就能夠將數據綁定到控件。下列代碼顯示如何將 XML 數據源綁定到下拉列表控件。
<asp:dropdownlist id="DropDownList1" runat="server" datatextfield="state" datasourceid="XMLDataSource1" autopostback="true" /> |
請注意,ASP.NET 1.x 和 ASP.NET 2.0 中數據綁定的主要區別在于提供程序模型是否自動同步發生了更改的數據。換句話說,由于在數據源中置入了一個事件模型,如果修改支持數據源的數據,則自動更新綁定控件。
數據綁定控件
ASP.NET 2.0 引入了幾個用于顯示數據的新控件。這些新控件提供了一些比 ASP.NET 1.1 的 DataGrid 控件更優越的增強功能。
GridView 控件
ASP.NET 1.1 的 DataGrid 控件功能強大,使用靈活,允許顯示結構化數據,無需編寫大量代碼。但是,如果要操作 DataGrid 的內容(例如,編輯或對返回行進行排序),需要編寫適量的代碼,自定義控件并提供這些行為。
GridView 與 DataGrid 控件相似;但是,您也能夠通過向導一步步聲明性地配置控件,啟用像編輯和顯示多頁行數據這樣的通用任務。
配置 GridView
為了說明實現上述功能多么輕松,請思考這個例子:根據下拉列表的選擇項顯示查詢結果。只需將 GridView 控件拖放到頁面上,配置控件以根據下拉列表的選擇項自動顯示結果。

圖 5. 將 GridView 綁定到 DropDown 列表
要配置 GridView 控件,您必須通過 Configure Data Source Wizard 將它綁定到數據源。圖 6 還顯示 DataGrid 對象提供的 Enable Paging、Enable Sorting 和 Enable Selection 選項。
在 Configure Data Source 窗口中,選擇適當的表格,然后選擇所需的元素。窗口底部顯示自動生成的 SQL 查詢語句。

圖 6. 編輯 SQL 數據源
下一步,單擊 WHERE 按鈕,配置 GridView 中顯示的記錄的條件;在下面的窗口中選擇 patientID 列,設置操作符和源選項。當源選項設置為 Control 時,當前頁面中的所有控件將自動填充到 Parameter 屬性的 Control ID 字段中。從列表中選擇想要連接的控件。配置好參數和默認值(如果需要)后,單擊 Add 按鈕,再單擊 OK 按鈕進行確認。

圖 7. 查詢編輯器對話框
生成的 select 語句可通過 Configure DataSource 窗口查看。
在 ASP 和 ASP.NET 應用程序中,必須編寫代碼完成所有這些過程,還要編寫 HTML 代碼來顯示格式化的結果。新的 GridView 控件生成了以下結果,沒有附加任何代碼(請注意,Edit 和 Delete 鏈接是自動可見的,并注意生成的 SQL):

圖 8. 綁定到下拉列表的 GridView 控件顯示的結果
DetailsView 控件
DetailsView 控件與 GridView 控件相似,它使用完全相同的安裝機制。GridView 控件在一頁顯示多條記錄,而 DetailsView 控件一次只顯示一條記錄。

圖 9. 在 DetailsView 控件中顯示一條記錄
因此,DetailsView 控件與 GridView 控件形成了很好的互補。將 DetailsView 連接到 GridView 可以更好地控制更新個別項目或插入新項目的方式和時機。
FormView 控件
使用上述配置步驟,我們還能夠為 ASP.NET 的開發配置另一個新控件 — FormView 控件。FormView 控件支持非常靈活的 UI 布局。下面的示例顯示使用 FormView 控件查看單個數據庫記錄。

圖 10. FormView ItemTemplate 輸出
像 ItemTemplate 和 EditItemTemplate 這樣不同的模板用于查看和修改數據庫記錄,無需任何自定義代碼。

圖 11. FormView EditTemplate 輸出
新增的 ASP.NET 2.0 數據功能
除了前面章節介紹的新控件,ASP.NET 2.0 還提供幾個與數據訪問有關的新功能,這些功能有助于提高數據驅動應用程序的性能和安全性。
性能
Web 應用程序的性能通常可以通過兩種機制來改進。首先,Web 應用程序層能夠緩存盡可能多的數據,減少了不必要的數據層調用。其次,Web 應用程序可以減少調用數據層的次數和大小。
數據源緩存
SQLDataSource 和 ObjectDataSource 支持數據層緩存。通過設置數據源對象的一些屬性,程序員不用開發任何自定義代碼,即可使用緩存 api。數據源對象將自動管理底層存儲機制的一致性。
SQL 緩存依賴關系
對大多數數據驅動的 Web 站點來說,緩存數據是復雜的任務。Web 站點需要使用緩存來提高性能,但是更新數據的需求也很迫切。ASP.NET 1.x 能將頁面緩存一段時間,并通過輸入參數(QUERYSTRING 或 POST 參數)進行組織。
<%@ outputcache duration="3600" varybyparam="ProdID" %> |
以上代碼根據變量 ProdID (產品 id)在內存中緩存頁面一小時。
如果在應用程序的其他地方更新了下層數據,緩存數據將出現問題。例如,考慮將一個產品目錄頁面通過產品 ID 進行緩存。如果從一個管理站點更新產品信息(例如,可用數量或價格),過期數據仍保留在緩存中,并顯示給客戶。在 ASP.NET 1.x 中,必須等待緩存失效,或使用 Response.RemoveOutputCacheItem 強制緩存失效。
ASP.NET 2.0 通過實現表格級 SQL 通知來支持數據庫緩存依賴關系。更改數據時,一個表格級依賴關系通知頁面。下面的代碼將產品頁面緩存了一小時,但是向數據庫表添加了一個依賴關系。
<%@ outputcache duration="3600" varybyparam="ProdID" sqldependency="MyDatabase:Products" %> |
向 Products 表格添加新的 SQLDependency 屬性后,不論表格發生任何更改,緩存過的頁面都將失效。SQLDependency 屬性必須引用在 web.config 文件中配置的 Microsoft SQL Server DataSource。DataSource 標識了使依賴關系通知有效的數據庫連接和參數。
自定義 SQL 依賴關系
雖然默認情況下 SQLDependency 類只支持 Microsoft SQL Server,但是您能夠通過 machine.config 和 web.config 文件替代和重新配置類。這個功能允許您創建自定義的 SQLDependency 類,為任何 DataSource(包括 Oracle、Sybase 或其他任何數據庫)提供相似的功能。
數據源緩存
在 ASP.NET 2.0 中,緩存數據的另一個方法是使用直接置入數據源的緩存機制。例如,SQLDataSource 和 ObjectDataSource 類都支持通過 EnableCaching 屬性直接緩存。只需將該屬性設置為 true,數據源將自動緩存從數據存儲提取的數據。緩存將根據 CacheDuration 屬性設定的時間或通過類似于頁面級指令的 SQLCacheDependency 失效。由于在數據源控件中置入了這些功能,無需編寫任何代碼,您就能快速、輕松地實現緩存。
改進的 DataSet 遠程處理支持
對 ASP.NET 1.1 最多的抱怨是:由于通常要將 DataSet 序列化為 XML,因此通過 .NET 遠程處理發送 DataSet 比發送其他序列化二進制表示形式慢。ASP.NET 2.0 將 DataSet 作為二進制序列化表示形式進行傳輸,以幫助減少 DataSet 的傳輸大小和傳遞信息所需的傳輸時間。
安全性
ASP.NET 2.0 提供的一項服務能夠加密配置文件的任何部分。通過加密,您能夠更安全地存儲應用程序內的信息。例如,可以加密 Web.config 文件的 ConnectionString 部分來保護所有的敏感信息。配置加密允許您安全地存儲像連接字符串這樣的信息。
加密配置信息時,您可以使用政府標準加密算法,例如三重 DES。因為加密數據存儲在配置文件中,所以應用程序不依賴于注冊表。
小結
ASP.NET 2.0 致力于幫助您靈活地控制數據,通過在新增的數據控件中封裝功能,減少訪問數據和顯示數據所需的代碼數量。新的數據訪問模型和控件減少的數據訪問代碼多達 70%。現在,傳統的 ASP 或 ASP.NET 1.1 應用程序中需要手動設計的許多功能都已內置到新的數據控件中了。數據訪問的新體系結構也是可擴展的,是為訪問多種不同的數據源數據而設計的,這些數據源包括數據庫、XML 文件、平面文件、數據流等等。作為一名企業級開發人員,您能夠利用新的體系結構連接任何后端數據源,而仍然使用一個簡單的前端接口。