天天看點

Microsoft Application Blocks for .NETMicrosoft Application Blocks for .NET

Microsoft Application Blocks for .NET

Data Access Application Block 概述

Chris Brooks、Graeme Malcolm、Alex Mackman、Edward Jezierski

Microsoft Corporation

2002 年 4 月

摘要:

Data Access Application Block 是一個 .NET 元件,包含優化的資料通路代碼,可以幫助使用者調用存儲過程以及向 SQL Server 資料庫發出 SQL 文本指令。它傳回 SqlDataReader、DataSet 和 XmlReader 對象。您可以在自己的 .NET 應用程式中将其作為構造塊來使用,以減少需要建立、測試和維護的自定義代碼的數量。您可以下載下傳完整的 C# 和 Visual Basic .NET 源代碼以及綜合文檔。

簡介

您是否正在從事 .NET 應用程式資料通路代碼的設計和開發?您是否覺得自己總是在反複編寫相同的資料通路代碼?您是否曾經将資料通路代碼包裝在 Helper 函數中,以便能夠在一行中調用存儲過程?如果是,那麼 Microsoft® Data Access Application Block for .NET 正是為您設計的。

Data Access Application Block 将通路 Microsoft SQL Server™ 資料庫的性能和資源管理方面的最佳經驗封裝在一起。您可以很友善地在自己的 .NET 應用程式中将其作為構造塊使用,從頁減少了需要建立、測試和維護的自定義代碼的數量。

尤其是,Data Access Application Block 可以幫助您:

  • 調用存儲過程或 SQL 文本指令。
  • 指定參數詳細資訊。
  • 傳回 SqlDataReader、DataSet 或 XmlReader 對象。

例如,在引用了 Data Access Application Block 的應用程式中,您可以簡單地在一行代碼中調用存儲過程并生成 DataSet,如下所示:

[Visual Basic]
Dim ds As DataSet = SqlHelper.ExecuteDataset( _
      connectionString, _
      CommandType.StoredProcedure, _
      "getProductsByCategory", _
      new SqlParameter("@CategoryID", categoryID))
 
[C#]
DataSet ds = SqlHelper.ExecuteDataset( 
      connectionString,
      CommandType.StoredProcedure,
      "getProductsByCategory",
      new SqlParameter("@CategoryID", categoryID)); 
  
        
注意: Application Block for .NET(用于 .NET 的應用程式塊)是基于對成功的 .NET 應用程式進行詳細研究而設計的。它以源代碼的形式提供,您可以原樣使用,也可以針對自己的應用程式進行自定義。該應用程式塊并不代表未來 Microsoft ADO.NET 程式庫的發展方向。Microsoft ADO.NET 程式庫是為在各種使用情況下實作對資料通路行為的精确控制而建立的。将來的 ADO.NET 版本可能會使用不同的模型來實作這個方案。

本概述的其餘部分包括以下内容:

Data Access Application Block 包括哪些内容?

下載下傳和安裝 Data Access Application Block

使用 Data Access Application Block

内部設計

常見問題

回報和支援

合作者

Data Access Application Block 包括哪些内容?

提供了 Data Access Application Block 的源代碼以及快速入門示例應用程式,您可以使用這些應用程式測試其功能。Data Access Application Block 還包括綜合文檔,可以幫助您使用和了解所提供的代碼。

Visual Studio .NET 項目

提供了 Data Access Application Block 的 Microsoft Visual Basic® .NET 和 Microsoft Visual C#™ 源代碼,以及每種語言的快速入門示例用戶端應用程式,您可以使用這些應用程式測試常見的方案。這有助于加深您對 Data Access Application Block 的工作原理的了解。您還可以自定義源代碼以滿足自己的需要。

您可以編譯 Visual Basic 和 C# Microsoft.ApplicationBlocks.Data 項目,以生成一個名為

Microsoft.ApplicationBlocks.Data.dll

的程式集。該程式集包括一個

SqlHelper

類(其中包含用于執行資料庫指令的核心功能)和一個

SqlhelperParameterCache

類(提供參數發現和緩存功能)。

文檔

Data Access Application Block 的文檔主要包括以下内容:

  • 使用 Data Access Application Block 開發應用程式 。本部分包括快速入門示例,其中包含多種常見的使用情況,可以幫助您快速輕松地掌握 Data Access Application Block(資料通路應用程式塊)的使用。
  • Data Access Application Block 的設計與實作 。本部分包括背景設計原理資訊,以便使用者深入了解 Data Access Application Block 的設計與實作。
  • 部署和運作 。本部分包括安裝資訊,其中包含部署和更新選項以及與安全性有關的資訊。
  • 參考 。本部分包含綜合的 API 參考,其中詳細介紹了構成 Data Access Application Block 的類和接口。

系統要求

要運作 Data Access Application Block,需要滿足以下要求:

  • Microsoft Windows® 2000、Windows XP Professional
  • .NET Framework SDK(英文)的 RTM 版本
  • Visual Studio® .NET 的 RTM 版本(推薦,但不必需)
  • SQL Server 7.0 或更高版本的資料庫伺服器

下載下傳并安裝 Data Access Application Block

您可以擷取一個包含已簽名的 Data Access Application Block 程式集和綜合文檔的 Windows 安裝程式檔案。

安裝程序将在您的“程式”菜單中建立一個

Microsoft Application Blocks for .NET

(用于 .NET 的 Microsoft 應用程式塊)子菜單。該子菜單中有一個

Data Access

(資料通路)子菜單,其中包括用于啟動文檔的選項和用于啟動 Data Access Application Block Visual Studio .NET 解決方案的選項。

請轉到 MSDN Downloads(英文)進行下載下傳。

使用 Data Access Application Block

本節讨論如何使用 Data Access Application Block 來執行資料庫指令和管理參數。圖 1 顯示了 Data Access Application Block 的主要元素。

Microsoft Application Blocks for .NETMicrosoft Application Blocks for .NET
圖 1:Data Access Application Block SqlHelper

類提供了一組靜态方法,可以用來向 SQL Server 資料庫發出許多各種不同類型的指令。

SqlHelperParameterCache

類提供指令參數緩存功能,可以用來提高性能。該類由許多

Execute

方法(尤其是那些隻運作存儲過程的重寫方法)在内部使用。資料通路用戶端也可以直接使用它來緩存特定指令的特定參數集。

使用 SqlHelper 類執行指令

SqlHelper

類提供了五種

Shared

(Visual Basic) 或

static

(C#) 方法,它們是:

ExecuteNonQuery

ExecuteDataset

ExecuteReader

ExecuteScalar

ExecuteXmlReader

。實作的每種方法都提供一組一緻的重載。這提供了一種很好的使用

SqlHelper

類來執行指令的模式,同時為開發人員選擇通路資料的方式提供了必要的靈活性。每種方法的重載都支援不同的方法參數,是以開發人員可以确定傳遞連接配接、事務和參數資訊的方式。類中實作的所有方法都支援以下重載:

[Visual Basic]
Execute* (ByVal connection As SqlConnection, _
          ByVal commandType As CommandType, _
          ByVal CommandText As String)

Execute* (ByVal connection As SqlConnection, _
          ByVal commandType As CommandType, _
          ByVal commandText As String, _
          ByVal ParamArray commandParameters() As SqlParameter)

Execute* (ByVal connection As SqlConnection, _
          ByVal spName As String, _
          ByVal ParamArray parameterValues() As Object)

Execute* (ByVal transaction As SqlTransaction, _
          ByVal commandType As CommandType, _
          ByVal commandText As String)

Execute* (ByVal transaction As SqlTransaction, _
          ByVal commandType As CommandType, _
          ByVal commandText As String, _
          ByVal ParamArray commandParameters() As SqlParameter)

Execute* (ByVal transaction As SqlTransaction, _
          ByVal spName As String, _
          ByVal ParamArray parameterValues() As Object)

[C#]
Execute* (SqlConnection connection, CommandType commandType, 
          string commandText)

Execute* (SqlConnection connection, CommandType commandType,
          string commandText, params SqlParameter[] commandParameters)

Execute* (SqlConnection connection, string spName, 
          params object[] parameterValues)

Execute* (SqlConnection connection, 
          CommandType commandType, string commandText)

Execute* (SqlConnection connection,
          CommandType commandType, string commandText, 
          params SqlParameter[] commandParameters)

Execute* (SqlConnection connection,
          string spName, params object[] parameterValues)
      

除這些重載以外,除

ExecuteXmlReader

之外的其他方法還提供了另一種重載:允許将連接配接資訊作為連接配接字元串而不是連接配接對象來傳遞,如下面的方法簽名所示:

[Visual Basic]
Execute* (ByVal connectionString As String, _
          ByVal commandType As CommandType, _
          ByVal commandText As String)

Execute* (ByVal connectionString As String, _
          ByVal commandType As CommandType, _
          ByVal commandText As String, _
          ByVal ParamArray commandParameters() As SqlParameter)

Execute* (ByVal connectionString As String, _
          ByVal spName As String, _
          ByVal ParamArray parameterValues() As Object)

[C#]
Execute* (string connectionString, CommandType commandType, 
          string commandText)

Execute* (string connectionString, CommandType commandType, 
          string commandText, 
          params SqlParameter[] commandParameters)

Execute* (string connectionString, string spName, 
          params object[] parameterValues)
      
注意: ExecuteXmlReader 不支援連接配接字元串,因為:與 SqlDataReader 對象不同, XmlReader 對象在 XmlReader 關閉時沒有提供自動關閉連接配接的方法。如果用戶端傳遞了連接配接字元串,那麼當用戶端完成對 XmlReader 的操作後,将無法關閉與 XmlReader 相關聯的連接配接對象。

通過參考 Data Access Application Block 程式集并導入 Microsoft.ApplicationBlocks.Data 命名空間,您可以輕松編寫使用任何一種

SqlHelper

類方法的代碼,如下面的代碼示例所示:

[Visual Basic]
Imports Microsoft.ApplicationBlocks.Data

[C#]
using Microsoft.ApplicationBlocks.Data;
        

導入命名空間後,您可以調用任何 Execute* 方法,如下面的代碼示例所示:

[Visual Basic]
Dim ds As DataSet = SqlHelper.ExecuteDataset( _
   "SERVER=(local);DATABASE=Northwind;INTEGRATED SECURITY=True;",
     _
   CommandType.Text, "SELECT * FROM Products")

[C#]
DataSet ds = SqlHelper.ExecuteDataset( 
   "SERVER=DataServer;DATABASE=Northwind;INTEGRATED
     SECURITY=sspi;", _
   CommandType.Text, "SELECT * FROM Products");
      

使用 SqlHelperParameterCache 類管理參數

SqlHelperParameterCache

類提供了三種可以用來管理參數的公共共享方法。它們是:

  • CacheParameterSet 。用于将 SqlParameters 數組存儲到緩存中。
  • GetCachedParameterSet 。用于檢索緩存的參數數組的副本。
  • GetSpParameterSet 。一種重載方法,用于檢索指定存儲過程的相應參數(首先查詢一次資料庫,然後緩存結果以便将來查詢)。

緩存和檢索參數

通過使用

CacheParameterSet

方法,可以緩存

SqlParameter

對象數組。此方法通過将連接配接字元串和指令文本連接配接起來建立一個鍵,然後将參數數組存儲在

Hashtable

中。

要從緩存中檢索參數,請使用

GetCachedParameterSet

方法。此方法将傳回一個 SqlParameter 對象數組,這些對象已使用緩存(與傳遞給該方法的連接配接字元串和指令文本相對應)中的參數的名稱、值、方向和資料類型等進行了初始化。

注意: 用作參數集的鍵的連接配接字元串通過簡單的字元串比較進行比對。用于從 GetCachedParameterSet 中檢索參數的連接配接字元串必須與用來通過 CacheParameterSet 來存儲這些參數的連接配接字元串完全相同。文法不同的連接配接字元串即使語義相同,也不會被認為是比對的。

以下代碼顯示了如何使用 SqlHelperParameterCache 類來緩存和檢索 Transact-SQL 語句的參數。

[Visual Basic]
' 初始化連接配接字元串和指令文本
' 它們将構成用來存儲和檢索參數的鍵
Const CONN_STRING As String = _
  "SERVER=(local); DATABASE=Northwind; INTEGRATED SECURITY=True;"
Dim sql As String = _
       "SELECT ProductName FROM Products " + _
       "WHERE [email protected] AND SupplierID = @Sup"

' 緩存參數
Dim paramsToStore(1) As SqlParameter
paramsToStore(0) = New SqlParameter("@Cat", SqlDbType.Int)
paramsToStore(1) = New SqlParameter("@Sup", SqlDbType.Int)
SqlHelperParameterCache.CacheParameterSet(CONN_STRING, _
                                          sql, _
                                          paramsToStore)

' 從緩存中檢索參數
Dim storedParams(1) As SqlParameter
storedParams = SqlHelperParameterCache.GetCachedParameterSet( _
                                                 CONN_STRING, sql)
storedParams(0).Value = 2
storedParams(1).Value = 3

' 在指令中使用參數
Dim ds As DataSet
ds = SqlHelper.ExecuteDataset(CONN_STRING, _
                              CommandType.Text, _
                              sql, storedParams)

[C#]
// 初始化連接配接字元串和指令文本
// 它們将構成用來存儲和檢索參數的鍵
const string CONN_STRING =
  "SERVER=(local); DATABASE=Northwind; INTEGRATED SECURITY=True;";
string spName = "SELECT ProductName FROM Products " + 
                "WHERE [email protected] AND SupplierID = @Sup";

// 緩存參數
SqlParameter[] paramsToStore = new SqlParameter[2];
paramsToStore[0] = New SqlParameter("@Cat", SqlDbType.Int);
paramsToStore[1] = New SqlParameter("@Sup", SqlDbType.Int);
SqlHelperParameterCache.CacheParameterSet(CONN_STRING, 
                                          sql, 
                                          paramsToStore);

// 從緩存中檢索參數
SqlParameter storedParams = new SqlParameter[2];
storedParams = SqlHelperParameterCache.GetCachedParameterSet(
                                              CONN_STRING, sql);
storedParams(0).Value = 2;
storedParams(1).Value = 3;

// 在指令中使用參數
DataSet ds;
ds = SqlHelper.ExecuteDataset(CONN_STRING, 
                              CommandType.StoredProcedure,
                              sql, storedParams);
      

檢索存儲過程參數

SqlHelperParameterCache

還提供了針對特定存儲過程檢索參數數組的方法。一種名為

GetSpParameterSet

的重載方法提供了此功能,它包含兩種實作。該方法嘗試從緩存中檢索特定存儲過程的參數。如果這些參數尚未被緩存,則使用 .NET 的 SqlCommandBuilder 類從内部檢索,并将它們添加到緩存中,以便用于後續的檢索請求。然後,為每個參數指定相應的參數設定,最後将這些參數以數組形式傳回給用戶端。以下代碼顯示了如何檢索 Northwind 資料庫中

SalesByCategory

存儲過程的參數。

[Visual Basic]
' 初始化連接配接字元串和指令文本
' 它們将構成用來存儲和檢索參數的鍵
Const CONN_STRING As String = _
  "SERVER=(local); DATABASE=Northwind; INTEGRATED SECURITY=True;"
Dim spName As String = "SalesByCategory"

' 檢索參數
Dim storedParams(1) As SqlParameter
storedParams = SqlHelperParameterCache.GetSpParameterSet( _
                                          CONN_STRING, spName)
storedParams(0).Value = "Beverages"
storedParams(1).Value = "1997"

' 在指令中使用參數
Dim ds As DataSet
ds = SqlHelper.ExecuteDataset(CONN_STRING, _
                              CommandType.StoredProcedure, _
                              spName, storedParams)

[C#]
// 初始化連接配接字元串和指令文本
// 它們将構成用來存儲和檢索參數的鍵
const string CONN_STRING = 
  "SERVER=(local); DATABASE=Northwind; INTEGRATED SECURITY=True;";
string spName = "SalesByCategory";

// 檢索參數
SqlParameter storedParams = new SqlParameter[2];
storedParams = SqlHelperParameterCache.GetSpParameterSet(
                                          CONN_STRING, spName);
storedParams[0].Value = "Beverages";
storedParams[1].Value = "1997";

// 在指令中使用參數
DataSet ds;
ds = SqlHelper.ExecuteDataset(CONN_STRING, 
                              CommandType.StoredProcedure,
                              spName, storedParams);
      

内部設計

Data Access Application Block 包含了完整的源代碼和有關其設計的綜合指南。本節介紹有關主要實作的詳細資訊。

SqlHelper 類實作詳細資訊

SqlHelper

類用于通過一組靜态方法來封裝資料通路功能。該類不能被繼承或執行個體化,是以将其聲明為包含專用構造函數的不可繼承類。

SqlHelper

類中實作的每種方法都提供了一組一緻的重載。這提供了一種很好的使用

SqlHelper

類來執行指令的模式,同時為開發人員選擇通路資料的方式提供了必要的靈活性。每種方法的重載都支援不同的方法參數,是以開發人員可以确定傳遞連接配接、事務和參數資訊的方式。在

SqlHelper

類中實作的方法包括:

  • ExecuteNonQuery 。此方法用于執行不傳回任何行或值的指令。這些指令通常用于執行資料庫更新,但也可用于傳回存儲過程的輸出參數。
  • ExecuteReader 。此方法用于傳回 SqlDataReader 對象,該對象包含由某一指令傳回的結果集。
  • ExecuteDataset 。此方法傳回 DataSet 對象,該對象包含由某一指令傳回的結果集。
  • ExecuteScalar 。此方法傳回一個值。該值始終是該指令傳回的第一行的第一列。
  • ExecuteXmlReader 。此方法傳回 FOR XML 查詢的 XML 片段。

除了這些公共方法外,

SqlHelper

類還包含一些專用函數,用于管理參數和準備要執行的指令。不管用戶端調用什麼樣的方法實作,所有指令都通過

SqlCommand

對象來執行。在

SqlCommand

對象能夠被執行之前,所有參數都必須添加到

Parameters

集合中,并且必須正确設定

Connection

CommandType

CommandText

Transaction

屬性。

SqlHelper

類中的專用函數主要用于提供一種一緻的方式,以便向 SQL Server 資料庫發出指令,而不考慮用戶端應用程式調用的重載方法實作。SqlHelper 類中的專用實用程式函數包括:

  • AttachParameters :該函數用于将所有必要的 SqlParameter 對象連接配接到正在運作的 SqlCommand。
  • AssignParameterValues :該函數用于為 SqlParameter 對象指派。
  • PrepareCommand :該函數用于對指令的屬性(如連接配接、事務環境等)進行初始化。
  • ExecuteReader :此專用 ExecuteReader 實作用于通過适當的 CommandBehavior 打開 SqlDataReader 對象,以便最有效地管理與閱讀器關聯的連接配接的有效期。

SqlHelperParameterCache 類實作詳細資訊

參數數組緩存在專用

Hashtable

中。從緩存中檢索的參數進行内部複制,這樣用戶端應用程式能夠更改參數值以及進行其他操作,而不會影響緩存的參數數組。專用共享函數

CloneParameters

可以實作此目的。

常見問題

此版本包含哪些新增功能?

與 Data Access Application Block Beta 2.0 版本相比,該 RTM 版本包含以下新增功能和變化:

  • SqlHelper 類方法的事務型重載不再需要 SqlConnection 參數。在此版本中,連接配接資訊從 SqlTransaction 對象中派生,是以不必在方法簽名中包含 SqlConnection 對象參數。
  • 現在, GetSpParameterSet 方法使用 ADO.NET CommandBuilder 類的 DeriveParameters 方法來确定存儲過程所需要的參數。這比 Beta 2.0 版本中直接通過查詢資料庫來檢索資訊的效率更高。

可以使用 XCOPY 部署方法來部署 Data Access Application Block 程式集嗎?

可以。Microsoft.ApplicationBlocks.Data.dll 程式集在編譯後可以使用 XCOPY 進行部署。

什麼時候應該使用 ExecuteDataset 方法,什麼時候應該使用 ExecuteReader 方法?

這個問題實際上是什麼時候應該傳回 DataSet 對象中的多個資料行,什麼時候應該使用 DataReader。答案取決于您的應用程式的特定需要,以及您在靈活性和原始性能之間的取舍。DataSet 為您提供資料的靈活的且斷開連接配接的關系視圖,而 DataReader 為您提供性能卓越的、隻讀的、僅向前光标。有關 DataSet 和 DataReader 的全面比較,請參閱 Data Access Architecture Guide(英文)。

如何使用 ExecuteDataset 傳回包含多個表的資料集?

通過建立一個可以傳回多個行集的存儲過程(通過執行多個 SELECT 語句或者對其他存儲過程進行嵌套調用),并使用 ExecuteDataset 方法執行該過程,您可以檢索包含多個表的資料集。

例如,假設您的資料庫包含以下存儲過程。

CREATE PROCEDURE GetCategories
AS
SELECT * FROM Categories
GO
CREATE PROCEDURE GetProducts
AS
SELECT * FROM Products
        

您可以建立一個主存儲過程來對這些過程進行嵌套調用,如下面的代碼示例所示。

CREATE PROCEDURE GetCategoriesAndProducts
AS
BEGIN
  EXEC GetCategories
  EXEC GetProducts
END
        

使用 ExecuteDataset 方法執行此主存儲過程将傳回一個 DateSet,其中包含兩個表:一個表包含分類資料,另一個表包含産品資料。

注意: ExecuteDataset 方法不提供為傳回的表指定自定義名稱的方法。第一個表的編号始終為 ,名稱為 Table ,第二個表的編号為 1 ,名稱為 Table1 ,依此類推。

還有其他的應用程式塊嗎?

Data Access Application Block 是即将釋出的幾個應用程式塊之一。這些應用程式塊可以解決開發人員在不同項目中遇到的共同問題。它們可以快速友善地插入到 .NET 應用程式中。

回報和支援

如果您對 Data Access Application Block 有任何問題、意見和建議,請向 [email protected] 發送電子郵件,我們将及時提供回報。

Application Blocks for .NET 旨在協助開發 .NET 分布式應用程式。示例代碼和文檔都按原樣提供。盡管已經過測試并被認為是穩定的代碼集,但我們并不象傳統的 Microsoft 産品那樣對其提供支援。

我們還建立了一個新聞討論區,可以幫助您使用 Application Blocks for .NET(.NET 應用程式塊)。您可以通過新聞討論區在聯機的開放論壇中向同行、同僚和 Microsoft 支援專家咨詢。

其他人也可以從您的問題和評論中獲益,我們的開發小組将每天檢視新聞討論區:

新聞討論區:基于 Web 的讀者

http://msdn.microsoft.com/newsgroups/loadframes.asp?icp=msdn&slcid=us&newsgroup=microsoft.public.dotnet.distributed_apps(英文)

新聞討論區:NNTP 讀者

news://msnews.microsoft.com/microsoft.public.dotnet.distributed_apps(英文)

您想學習和利用 .NET 的功能嗎?歡迎您與 Microsoft Technology Centers 的技術專家并肩工作,您将學到最好的開發經驗。有關詳細資訊,請通路 http://www.microsoft.com/business/services/mtc.asp(英文)。

您需要更多的幫助嗎?請通路新增的客戶支援服務 Advisory Services,該解決方案可以滿足您小規模的咨詢需要。有關 Advisory Services 的詳細資訊,請通路 http://support.microsoft.com/default.aspx?scid=FH;EN-US;offer58&FR=0&SD=GN&LN=EN-US&CT=SD&SE=NONA(英文)。

更多資訊

Data Access Application Block 的設計和開發是建立在 Data Access in .NET Architecture Guide(英文)中讨論的最佳開發經驗和通用設計原則基礎之上的。請閱讀該指南,以了解有關資料通路的詳細資訊。

合作者

衷心感謝以下投稿人和審閱人:Susan Warren、Brad Abrams、Andy Dunn、Michael Day、Mark Ashton、Gregory Leake、Steve Busby、Kenny Jones、David Schleifer、Andrew Roubin (Vorsite Corp.)、Jeffrey Richter (Wintellect)、Bernard Chen (Sapient) 和 Matt Drucker (Turner Broadcasting)。

同時感謝内容組的以下成員:Tina Burden (Entirenet)、Shylender Ramamurthy (Infosys Technologies Ltd) 和 Filiberto Selvas Patino。

繼續閱讀