設定資料存取層的連線和命令層級設定 (VB)

作者:Scott Mitchell

下載 PDF

具型別數據集內的 TableAdapters 會自動負責連線到資料庫、發出命令,以及填入 DataTable 並填入結果。 不過,有時候我們想要自行處理這些詳細數據,在本教學課程中,我們會瞭解如何存取 TableAdapter 中的資料庫連接和命令層級設定。

簡介

在整個教學課程系列中,我們已使用具型別數據集來實作分層架構的數據存取層和商務物件。 如 第一個教學課程所述,具類型的 DataSet s DataTables 可作為數據的存放庫,而 TableAdapters 會做為包裝函式來與資料庫通訊,以擷取和修改基礎數據。 TableAdapters 會封裝處理資料庫時涉及的複雜度,並讓我們不必撰寫程式代碼以連線到資料庫、發出命令,或將結果填入 DataTable。

不過,有時候我們需要鑽研 TableAdapter 的深度,並撰寫可直接與 ADO.NET 物件搭配運作的程序代碼。 例如,在交易內包裝資料庫修改教學課程中,我們已將方法新增至 TableAdapter,以開始、認可和回復 ADO.NET 交易。 這些方法使用指派給 TableAdapter s SqlCommand 物件的內部手動建立SqlTransaction物件。

在本教學課程中,我們將檢查如何存取 TableAdapter 中的資料庫連接和命令層級設定。 特別是,我們會將功能新增至 ProductsTableAdapter ,以存取基礎 連接字串 和命令逾時設定。

使用 ADO.NET 處理數據

Microsoft .NET Framework 包含一系列專為處理數據而設計的類別。 這些類別位於 命名空間內System.Data,稱為 ADO.NET 類別。 ADO.NET 保護底下的某些類別會系結至特定數據提供者。 您可以將數據提供者視為可讓資訊在 ADO.NET 類別與基礎數據存放區之間流動的通道。 有一般化提供者,例如 OleDb 和 ODBC,以及專為特定資料庫系統設計的提供者。 例如,雖然可以使用 OleDb 提供者連線到 Microsoft SQL Server 資料庫,但 SqlClient 提供者會更有效率,因為它專為 SQL Server 而設計和優化。

以程式設計方式存取資料時,通常會使用下列模式:

  1. 建立資料庫的連線。
  2. 發出命令。
  3. 針對 SELECT 查詢,請使用產生的記錄。

每個步驟都有個別的 ADO.NET 類別。 例如,若要使用 SqlClient 提供者連線到資料庫,請使用 類別SqlConnection。 若要對資料庫發出 INSERTUPDATEDELETESELECT 命令,請使用 SqlCommand 類別

除了在交易中包裝資料庫修改教學課程之外,我們不需要自行撰寫任何低階 ADO.NET 程式代碼,因為 TableAdapters 自動產生的程式代碼包含連線到資料庫、發出命令、擷取數據,並將該數據填入 DataTable 所需的功能。 不過,有時可能需要自定義這些低階設定。 在接下來的幾個步驟中,我們將探討如何點選 TableAdapters 在內部使用的 ADO.NET 物件。

步驟 1:使用 Connection 屬性檢查

每個 TableAdapter 類別都有指定 Connection 資料庫連接資訊的屬性。 此屬性的數據類型和 ConnectionString 值是由 TableAdapter 組態精靈中所做的選取專案所決定。 回想一下,當我們第一次將 TableAdapter 新增至具類型數據集時,此精靈會要求我們提供資料庫來源 (請參閱圖 1) 。 第一個步驟中的下拉式清單包含組態檔中指定的資料庫,以及伺服器總管數據 Connections的任何其他資料庫。 如果我們想要使用的資料庫不存在於下拉式清單中,可以按兩下 [新增連線] 按鈕並提供所需的連線資訊來指定新的資料庫連線。

TableAdapter 設定精靈的第一個步驟

圖 1:TableAdapter 設定精靈的第一個步驟 (按兩下以檢視大小完整的映像)

讓我們花點時間檢查 TableAdapter s Connection 屬性的程序代碼。 如 建立數據存取層 教學課程所述,我們可以移至 [類別檢視] 視窗,向下切入至適當的類別,然後按兩下成員名稱,以檢視自動產生的 TableAdapter 程式代碼。

流覽至 [類別檢視] 視窗,方法是移至 [檢視] 功能表,然後選擇 [類別檢視] (,或輸入 Ctrl+Shift+C) 。 從 [類別檢視] 視窗的上半部向下切入至 NorthwindTableAdapters 命名空間,然後選取 ProductsTableAdapter 類別。 這會在 [類別檢視] 的下半部顯示 ProductsTableAdapter s 成員,如圖 2 所示。 按兩下 Connection 屬性以查看其程式代碼。

按兩下類別檢視中的連接屬性,以檢視其自動產生的程式代碼

圖 2:Double-Click 類別檢視中的 Connection 屬性,以檢視其自動產生的程式代碼

TableAdapter s Connection 屬性和其他連線相關程序代碼如下:

Private _connection As System.Data.SqlClient.SqlConnection
Private Sub InitConnection()
    Me._connection = New System.Data.SqlClient.SqlConnection
    Me._connection.ConnectionString = _
        ConfigurationManager.ConnectionStrings("NORTHWNDConnectionString").ConnectionString
End Sub
Friend Property Connection() As System.Data.SqlClient.SqlConnection
    Get
        If (Me._connection Is Nothing) Then
            Me.InitConnection
        End If
        Return Me._connection
    End Get
    Set
        Me._connection = value
        If (Not (Me.Adapter.InsertCommand) Is Nothing) Then
            Me.Adapter.InsertCommand.Connection = value
        End If
        If (Not (Me.Adapter.DeleteCommand) Is Nothing) Then
            Me.Adapter.DeleteCommand.Connection = value
        End If
        If (Not (Me.Adapter.UpdateCommand) Is Nothing) Then
            Me.Adapter.UpdateCommand.Connection = value
        End If
        Dim i As Integer = 0
        Do While (i < Me.CommandCollection.Length)
            If (Not (Me.CommandCollection(i)) Is Nothing) Then
                CType(Me.CommandCollection(i), _
                    System.Data.SqlClient.SqlCommand).Connection = value
            End If
            i = (i + 1)
        Loop
    End Set
End Property

具現化 TableAdapter 類別時,成員變數 _connection 等於 NothingConnection存取 屬性時,它會先檢查成員變數是否已_connection具現化。 如果沒有,InitConnection則會叫用 方法,這個方法會具現_connection化,ConnectionString並將其屬性設定為從 TableAdapter 組態精靈第一個步驟指定的 連接字串 值。

Connection屬性也可以指派給 SqlConnection 物件。 這麼做會將新 SqlConnection 物件與每個 TableAdapter s SqlCommand 物件產生關聯。

步驟 2:公開 Connection-Level 設定

線上資訊應該會保留在 TableAdapter 內,且無法供應用程式架構中的其他層存取。 不過,當 TableAdapter 的連線層級資訊必須可供查詢、使用者或 ASP.NET 頁面存取或自定義時,可能會有一些情況。

讓我們擴充 ProductsTableAdapter DataSet 中的 Northwind ,以包含ConnectionString商業規則層可以使用的屬性來讀取或變更 TableAdapter 所使用的 連接字串。

注意

連接字串 是指定資料庫連接資訊的字串,例如要使用的提供者、資料庫的位置、驗證認證和其他資料庫相關設定。 如需各種數據存放區和提供者所使用的 連接字串 模式清單,請參閱 ConnectionStrings.com

建立數據存取層 教學課程中所述,具型別數據集的自動產生類別可透過使用部分類別來擴充。 首先,在資料夾下方~/App_Code/DAL名為 ConnectionAndCommandSettings 的專案中建立新的子資料夾。

新增名為 ConnectionAndCommandSettings 的子資料夾

圖 3:新增名為 的子資料夾 ConnectionAndCommandSettings

新增名為 ProductsTableAdapter.ConnectionAndCommandSettings.vb 的新類別檔案,並輸入下列程式代碼:

Namespace NorthwindTableAdapters
    Partial Public Class ProductsTableAdapter
        Public Property ConnectionString() As String
            Get
                Return Me.Connection.ConnectionString
            End Get
            Set(ByVal value As String)
                Me.Connection.ConnectionString = value
            End Set
        End Property
    End Class
End Namespace

這個部分類別會將名為 ConnectionString 的屬性新增Public至 類別,ProductsTableAdapter讓任何圖層讀取或更新 TableAdapter 基礎連線的 連接字串。

使用此部分類別建立 (並儲存) ,請開啟 類別 ProductsBLL 。 移至其中一個現有的方法並輸入 Adapter ,然後按句號鍵來啟動 IntelliSense。 您應該會看到 IntelliSense 中可用的新 ConnectionString 屬性,這表示您可以從 BLL 以程式設計方式讀取或調整此值。

公開整個連接物件

這個部分類別只會公開基礎連接物件的一個屬性: ConnectionString。 如果您想要讓整個連接物件超出 TableAdapter 的範圍,您也可以變更 Connection 屬性的保護層級。 我們在步驟 1 中檢查的自動產生程式代碼顯示 TableAdapter s Connection 屬性標示為 Friend,這表示它只能由相同元件中的類別存取。 不過,這可以透過 TableAdapter s ConnectionModifier 屬性進行變更。

Northwind開啟 DataSet,按兩下 ProductsTableAdapter Designer 中的 ,然後流覽至 屬性視窗。 您會在這個處看到設為 ConnectionModifier 預設值的 Assembly。 若要在 Connection Typed DataSet 元件之外提供 屬性,請將 ConnectionModifier 屬性變更為 Public

線上屬性的輔助功能層級可以透過 ConnectionModifier 屬性進行設定

圖 4Connection 屬性的輔助功能層級可以透過 ConnectionModifier 屬性設定 (按單擊即可檢視完整大小的影像)

儲存 DataSet,然後返回 ProductsBLL 類別。 如前所述,移至其中一個現有的方法並輸入 Adapter ,然後按句號鍵來啟動 IntelliSense。 清單應該包含 Connection 屬性,這表示您現在可以以程序設計方式從 BLL 讀取或指派任何連線層級設定。

TableAdapter 是由預設自動產生的 INSERTUPDATEDELETE 語句的主要查詢所組成。 這個主要查詢的 INSERTUPDATEDELETE 語句會透過 Adapter 屬性,在 TableAdapter 程式代碼中實作為 ADO.NET 數據配接器物件。 如同其 Connection 屬性, Adapter 屬性的數據類型是由所使用的數據提供者所決定。 由於這些教學課程使用 SqlClient 提供者,所以 Adapter 屬性的類型 SqlDataAdapter為 。

TableAdapter s Adapter 屬性有三個類型 SqlCommand 屬性,可用來發出 INSERTUPDATEDELETE 語句:

  • InsertCommand
  • UpdateCommand
  • DeleteCommand

SqlCommand物件負責將特定查詢傳送至資料庫,並具有下列屬性:CommandText,其中包含要執行的臨機操作 SQL 語句或預存程式;以及 Parameters,這是 物件的集合SqlParameter。 如我們在建立數據存取層教學課程中所見,這些命令物件可以透過 屬性視窗 來自定義。

除了其主要查詢之外,TableAdapter 還可以包含一個變數數目的方法,在叫用時,將指定的命令分派給資料庫。 主要查詢的命令物件和所有其他方法的命令對象都會儲存在 TableAdapter s CommandCollection 屬性中。

讓我們花點時間查看 DataSet 中Northwind針對這兩個屬性及其支援的成員變數和協助程式方法所產生的ProductsTableAdapter程式代碼:

Private WithEvents _adapter As System.Data.SqlClient.SqlDataAdapter
Private Sub InitAdapter()
    Me._adapter = New System.Data.SqlClient.SqlDataAdapter
    
    ... Code that creates the InsertCommand, UpdateCommand, ...
    ... and DeleteCommand instances - omitted for brevity ...
End Sub
Private ReadOnly Property Adapter() As System.Data.SqlClient.SqlDataAdapter
    Get
        If (Me._adapter Is Nothing) Then
            Me.InitAdapter
        End If
        Return Me._adapter
    End Get
End Property
Private _commandCollection() As System.Data.SqlClient.SqlCommand
Private Sub InitCommandCollection()
    Me._commandCollection = New System.Data.SqlClient.SqlCommand(8) {}
    ... Code that creates the command objects for the main query and the ...
    ... ProductsTableAdapter�s other eight methods - omitted for brevity ...
End Sub
Protected ReadOnly Property CommandCollection() As System.Data.SqlClient.SqlCommand()
    Get
        If (Me._commandCollection Is Nothing) Then
            Me.InitCommandCollection
        End If
        Return Me._commandCollection
    End Get
End Property

CommandCollection 屬性的程式Adapter代碼會密切模擬 屬性的程序Connection代碼。 有一個成員變數會保存屬性所使用的物件。 屬性 Get 存取子的開頭是檢查,以查看對應的成員變數是否為 Nothing。 如果是,則會呼叫初始化方法,以建立成員變數的實例,並指派核心命令相關屬性。

步驟 4:公開 Command-Level 設定

在理想情況下,命令層級信息應該會保留在數據存取層內。 不過,如果架構的其他層級需要這項資訊,則可以透過部分類別公開,就像使用連接層級設定一樣。

由於 TableAdapter 只有單 Connection 一屬性,因此公開連線層級設定的程式代碼相當簡單。 修改命令層級設定時,專案會比較複雜,因為 TableAdapter 可以有多個命令物件 ,也就是 InsertCommandUpdateCommandDeleteCommand,以及屬性中的 CommandCollection 命令物件數目可變。 更新命令層級設定時,必須將這些設定傳播到所有命令物件。

例如,假設 TableAdapter 中有一些查詢需要很長的時間才能執行。 使用 TableAdapter 執行其中一個查詢時,我們可能會想要增加命令對象的 CommandTimeout 屬性。 此屬性會指定等候命令執行的秒數,並預設為 30。

若要允許 CommandTimeout BLL 調整屬性,請使用步驟 2 中建立的部分類別檔案,將下列 Public 方法新增至 ProductsDataTable () ProductsTableAdapter.ConnectionAndCommandSettings.vb

Public Sub SetCommandTimeout(ByVal timeout As Integer)
    If Me.Adapter.InsertCommand IsNot Nothing Then
        Me.Adapter.InsertCommand.CommandTimeout = timeout
    End If
    If Me.Adapter.DeleteCommand IsNot Nothing Then
        Me.Adapter.DeleteCommand.CommandTimeout = timeout
    End If
    If Me.Adapter.UpdateCommand IsNot Nothing Then
        Me.Adapter.UpdateCommand.CommandTimeout = timeout
    End If
    For i As Integer = 0 To Me.CommandCollection.Length - 1
        If Me.CommandCollection(i) IsNot Nothing Then
            Me.CommandCollection(i).CommandTimeout = timeout
        End If
    Next
End Sub

這個方法可以從 BLL 或簡報層叫用,以針對該 TableAdapter 實例的所有命令問題設定命令逾時。

注意

AdapterCommandCollection 屬性會標示為 Private,這表示只能從 TableAdapter 內的程式代碼存取它們。 Connection不同於 屬性,這些存取修飾詞無法設定。 因此,如果您需要將命令層級屬性公開至架構中的其他層,您必須使用上述的部分類別方法,提供 Public 讀取或寫入 Private 命令物件的方法或屬性。

摘要

具型別數據集內的 TableAdapters 可用來封裝數據存取詳細數據和複雜度。 使用 TableAdapters,我們不需要擔心撰寫 ADO.NET 程式代碼來連線到資料庫、發出命令,或將結果填入 DataTable。 這一切都會自動為我們處理。

不過,有時可能需要自定義低階 ADO.NET 細節,例如變更 連接字串 或默認連線或命令逾時值。 TableAdapter 具有自動產生的 ConnectionAdapterCommandCollection 屬性,但這些屬性預設為 FriendPrivate。 您可以使用部分類別擴充 TableAdapter 來包含 Public 方法或屬性,來公開此內部資訊。 或者,您可以透過 TableAdapter s 屬性來設定 TableAdapter s ConnectionConnectionModifier 屬性存取修飾詞。

快樂的程序設計!

關於作者

Scott Mitchell 是 1998 年以來,1998 年與 Microsoft Web 技術合作的 篇 ASP/ASP.NET 書籍和 4GuysFromRolla.com 作者。 Scott 是獨立的顧問、訓練者和作者。 他的最新書籍是 Sams 在 24 小時內自行 ASP.NET 2.0。 您可以透過mitchell@4GuysFromRolla.com部落格連到,也可以透過其部落格來存取,網址為 http://ScottOnWriting.NET

特別感謝

本教學課程系列是由許多實用的檢閱者所檢閱。 本教學課程的首席檢閱者是 Burnadette、Sren Lauritsen、Teresa Murphy 和一位 Geisenow。 想要檢閱即將推出的 MSDN 文章嗎? 如果是,請將一行放在 mitchell@4GuysFromRolla.com。