Microsoft® Office 提供了多種存儲和管理數據的功能和工具,例如,數據訪問對象 (DAO)、ActiveX® 數據對象 (ADO)、Microsoft Word 郵件合并、Microsoft Excel Web 查詢、Microsoft Query、數據訪問頁、Microsoft Access 數據項目、Office 數據連接、Office 數據鏈接等等。而 Microsoft .NET 平臺則提供了其他的數據訪問功能和工具,例如,ADO.NET、.NET 數據連接和數據庫項目。
在本月的專欄中,我將介紹如何使用 Microsoft Visual Studio® .NET、Microsoft Visual Basic® .NET,特別是如何使用 ADO.NET 來解鎖和管理 Microsoft Access 數據。
既然 Office 已經提供了一系列數據訪問功能和工具,為什么不利用 Office 來管理它自己的數據呢?當然,在許多情況下,您可能希望使用適合某個特定數據任務的內置 Office 功能和工具。然而,ADO.NET 提供了一種添加數據連接和編寫數據解決方案代碼的統一方法,這種方法不同于 Office 中的多個數據入口點和數據訪問庫。
如果您愿意,仍然可以在 Visual Studio .NET 和 Visual Basic .NET 中調用 ADO 功能。但鑒于以下原因,與 ADO 相比,ADO.NET 在許多方面都是更好的數據訪問解決方案。
當然,如果希望利用 .NET 中的諸多新功能,就應該使用 .NET 數據訪問功能和工具。有關 .NET 平臺的詳細信息,請參閱以前的專欄 Introducing .NET to Office Developers(英文)。
圖 1 顯示了使用 ADO.NET 時要用到的主要對象。
圖 1:ADO.NET 對象模型中的主要對象(來源:Inside .NET Managed Providers [英文])
這些對象包括:
作為參考,在使用 ADO 的 Office Visual Basic for Applications (VBA) 中,可以通過以下方法打開羅斯文示例 Access 數據庫,將數據從 Products 表復制到 Recordset 對象,并報告記錄集中第一條數據記錄的某些數據:
' Office VBA 和 ADO 代碼 - ADOCode.bas。 Public Sub ADOExample() ' 首先設置對 ADO 庫的引用。 Dim objConn As ADODB.Connection Dim objRS As ADODB.Recordset Set objConn = New ADODB.Connection objConn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "User ID=Admin;" & _ "Data Source=C:\Program Files\Microsoft " & _ "Office\Office10\Samples\Northwind.mdb" objConn.Open Set objRS = objConn.Execute("SELECT * FROM Products") objRS.MoveFirst MsgBox Prompt:=objRS.Fields("ProductName").Value & ", " & _ objRS.Fields("UnitsInStock").Value objRS.Close objConn.Close End Sub
如果您以前在 ADO 中進行過編碼,則此 ADO 代碼是非常簡單的:
作為比較,下面是一些用于控制臺應用程序的 Visual Basic .NET 示例代碼,使用 ADO.NET 執行大體相同的操作,但它并不將數據放入記錄集,而是由一個 ADO.NET 數據讀取器保持與數據的連接:
' Visual Basic .NET 和 ADO.NET 代碼 - ADONETCode.vb。 ' 使用連接的 ADO.NET 數據訪問。 ' 控制臺應用程序。 Imports System.Data.OleDb Module Module1 Sub Main() ' 首先設置對 System.Data.dll 的引用。 Dim objConn As New OleDbConnection _ ("Provider=Microsoft.Jet.OLEDB.4.0;" & _ "User ID=Admin;" & _ "Data Source=C:\Program Files\Microsoft" & _ "Office\Office10\Samples\Northwind.mdb") objConn.Open() Dim objCmd As New OleDbCommand _ ("SELECT * FROM Products", objConn) Dim objDataReader As OleDbDataReader = objCmd.ExecuteReader objDataReader.Read() Console.Write(objDataReader.Item("ProductName") & ", " & _ objDataReader.Item("UnitsInStock")) End Sub End Module
下面是該代碼的工作方式:
Imports System.Data.OleDb
有助于減少訪問對象或對象的成員時所需的工作量。例如,盡管可以在 ADO 中編寫 ADODB.Recordset
代碼,但通常并不這樣做,因為已經引用了 ADODB 庫。同樣,盡管可以在 ADO.NET 中編寫 System.Data.OleDb.OleDbConnection
代碼,但如果已經導入了與 OleDbConnection 對象關聯的名稱空間 System.Data.OleDb(假設我們已預先設置了對 System.Data.dll 的引用),也就不需要進行編碼。
下面是另一段 Visual Basic .NET 示例代碼,執行與前面的 ADO.NET 示例相同的操作。但在這一示例中,數據將被復制到 ADO.NET 數據集,然后斷開與數據庫的連接:
' Visual Basic .NET 和 ADO.NET 代碼 - ADONETCode.vb。 ' 使用斷開連接的 ADO.NET 數據訪問。 ' 控制臺應用程序。 Imports System.Data.OleDb Module Module1 Sub Main() ' 首先設置對 System.Data.dll 的引用。 Dim objConn As New OleDbConnection _ ("Provider=Microsoft.Jet.OLEDB.4.0;" & _ "User ID=Admin;" & _ "Data Source=C:\Program Files\Microsoft" & _ "Office\Office10\Samples\Northwind.mdb") objConn.Open() Dim objAdapter As New OleDbDataAdapter _ ("SELECT * FROM Products", objConn) Dim objDataSet As New DataSet() objAdapter.Fill(objDataSet) With objDataSet.Tables("Table").Rows(0) Console.Write(.Item("ProductName") & ", " _ & .Item("UnitsInStock")) End With End Sub End Module
下面是此代碼與前一 ADO.NET 示例的區別:
雖然您可能希望在 Office VBA 中使用 ADO.NET 的新功能,但目前還不能這樣做。這是因為,如果運行 RegAsm.exe(.NET Frameworks SDK 中的程序集注冊工具)將 System.Data.dll 注冊為 COM(Office VBA 基于此技術),然后嘗試從 Office 引用生成的類型庫文件,則不會在 Office Visual Basic 的對象瀏覽器中顯示任何成員。這是因為 COM 不能識別核心的私有 ADO.NET 成員和參數化的構造函數。因此,至少在目前,還只能繼續在 Office VBA 中使用 ADO。
Visual Studio .NET 提供了許多便利工具用于訪問 Office 數據,包括創建可重復使用的數據連接、數據庫項目以及數據表單向導。
數據連接允許您一次性定義數據庫連接的詳細信息,然后在多個解決方案中重復使用該信息。下面的示例介紹如何在 Visual Studio .NET 中創建可重復使用的數據連接:
這樣就有了一個可以添加到 Visual Studio .NET 項目的可重復使用的數據連接。
下面基于這些步驟給出一個示例,說明如何創建 ADO.NET 對象,這些對象能夠與 Server Explorer(服務器資源管理器)窗口中的現有數據連接進行交互操作:
注意:在 Visual Studio .NET Beta 2 中,不會顯示 Fill Dataset(填充數據集)按鈕,以便生成實際填充 Dataset 對象的代碼??赡苄枰謩酉?Form_Load 或 Page_Load 事件添加代碼,如下所示:Me.OleDbDataAdapter1.Fill(DataSetName11)
。
下面的示例介紹如何在 Windows 窗體中添加數據網格,并綁定到前一示例中生成的現有數據集:
Me.OleDbDataAdapter1.Fill(DataSetName11)
。
提示:要在 Server Explorer(服務器資源管理器)窗口中沒有現有數據連接的情況下創建 ADO.NET 對象,請執行以下步驟:
Visual Studio .NET 數據庫項目允許您快速創建面向數據庫的解決方案。下面的示例介紹如何在 Visual Studio .NET 中創建數據庫項目:
Visual Studio .NET 數據表單向導允許您快速連接到數據庫,并生成簡單的用戶界面,用于顯示數據并與數據進行交互。要使用數據表單向導,請執行以下步驟:
注意:請確保將新數據表單設置為啟動表單,方法如下:在 Project(項目)菜單中,單擊 Properties(屬性)。展開 Common Properties(通用屬性)文件夾,單擊 General(常規),在 Startup object(啟動對象)列表中選擇該數據表單,然后單擊 OK(確定)。
注意:請確保將 DataSet1 中的數據綁定到數據表單,這可以通過向數據表單的 Load 事件插入以下代碼來實現:Me.OleDbDataAdapter1.Fill(objDataSet1)
為了向您演示更多的 ADO.NET 代碼,在本月專欄的最后,我將介紹幾個在 ADO.NET 中創建的擴展的代碼示例。
很多時候,您只是希望簡單地瀏覽數據,而并不需要在數據間來回瀏覽,也不需要更改數據(我們將此稱為“流水數據”)。ADO.NET 的 DataReader 對象是專門為此設計的。下面是我編寫的一段示例代碼,可以逐個讀取連接的數據庫中的所有選定數據:
' Visual Basic .NET 代碼。 ' 控制臺應用程序。 ' 引用: ' System ' System.Data ' System.XML Imports System.Data.OleDb ' 用于 OleDb 對象。 Imports Microsoft.VisualBasic.ControlChars ' 用于 CrLf 常量。 Module Module1 Sub Main() ' 創建并初始化 OleDbConnection、OleDbCommand ' 和 OleDbDataReader 對象。 Dim objConn As New _ OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" & _ "User ID=Admin;" & _ "Data Source=C:\Program Files\Microsoft" & _ "Office\Office10\Samples\Northwind.mdb") objConn.Open() ' 執行命令并將數據讀取器附加到 ' 所選數據。 Dim objCmd As New OleDbCommand("SELECT * FROM Products", _ objConn) Dim objReader As OleDbDataReader = objCmd.ExecuteReader ' 讀取數據并列出值。 Call ReadData(objReader) End Sub Public Sub ReadData(ByVal objReader As OleDbDataReader) ' 目的:列出給定數據讀取器的數據值。 ' 接受:objReader - 數據讀取器。 Dim intField As Integer ' 行中的當前字段。 Dim intColumn As Integer ' 當前列的名稱。 Dim blnColumns As Boolean = False ' 列名稱是否已 ' 列出。 With objReader ' 一次讀取一行,直至文件末尾。 Do While .Read = True For intField = 0 To .FieldCount - 1 ' 首先列出列名稱。 If blnColumns = False Then For intColumn = 0 To .FieldCount - 1 If intColumn = .FieldCount - 1 Then Console.Write(.GetName(intColumn) & _ CrLf) Else Console.Write(.GetName(intColumn) & _ ", ") End If Next intColumn ' 只列出一次列名稱。 blnColumns = True End If ' 列出當前行中每個字段的值。 If intField = .FieldCount - 1 Then Console.Write(.Item(intField) & CrLf) Else Console.Write(.Item(intField) & ", ") End If Next intField Loop End With ' 暫停,以便用戶在控制臺窗口中查看數據。 Console.Write("按任意鍵繼續...") Console.Read() End Sub End Module
下面是該代碼的工作方式:
Imports System.Data.OleDb
)有助于減少訪問對象或對象的成員時所需的工作量。類似地,對 OleDbConnection、OleDbCommand 和 OleDbDataReader 對象進行聲明和初始化,以分別代表數據庫連接、數據記錄和記錄游標。此代碼的真正核心是 ReadData 子例程。
ADO.NET 的 DataSet 對象是為斷開連接的數據而設計的。您可以在一個數據集中模擬整個數據庫的結構和數據,包括表、行、列、字段,甚至關系。處理完數據后,可以使數據集中的數據與原始數據庫中的數據同步。下面是我編寫的一段示例代碼,可以逐個讀取斷開連接的數據集中的所有數據。
' Visual Basic .NET 代碼。 ' 控制臺應用程序。 ' 引用: ' System ' System.Data ' System.XML Imports System.Data.OleDb ' 用于 OleDb 對象。 Imports Microsoft.VisualBasic.ControlChars ' 用于 CrLf 常量。 Module Module1 Sub Main() ' 創建并初始化 OleDbDataAdapter 和 DataSet 對象。 Dim objAdapter As New OleDbDataAdapter _ ("SELECT * FROM Products", _ "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "User ID=Admin;" & _ "Data Source=C:\Program Files\Microsoft" & _ "Office\Office10\Samples\Northwind.mdb") Dim objDataSet As New DataSet() ' 將所選數據復制到數據集。 objAdapter.Fill(objDataSet) ' 列出數據集中的數據值。 Call ListData(objDataSet) End Sub Public Sub ListData(ByVal objDataSet As DataSet) ' 目的:列出給定數據集的數據值。 ' 接受:objDataSet - 數據集。 Dim objTable As DataTable Dim intRow, intColumn As Integer ' 數據集中可能包含有多個表。 For Each objTable In objDataSet.Tables With objTable Console.Write("表" & _ .TableName "中的數據" & ":" & CrLf) ' 首先列出列名稱。 For intColumn = 0 To .Columns.Count - 1 If intColumn = .Columns.Count - 1 Then Console.Write(.Columns(intColumn).ColumnName _ & CrLf) Else Console.Write(.Columns(intColumn).ColumnName _ & ", ") End If Next intColumn ' 按行列出數據... For intRow = 0 To .Rows.Count - 1 ' ...然后按字段列出每行中的數據。 For intColumn = 0 To _ .Rows(intRow).ItemArray.Length - 1 If intColumn = _ .Rows(intRow).ItemArray.Length - 1 Then Console.Write(.Rows(intRow). _ ItemArray(intColumn) _ & CrLf) Else Console.Write(.Rows(intRow). _ ItemArray(intColumn) & ", ") End If Next intColumn Next intRow End With Next objTable ' 暫停,以便用戶在控制臺窗口中查看數據。 Console.Write("按任意鍵繼續...") Console.Read() End Sub End Module
下面是該代碼的工作方式:
Imports System.Data.OleDb
)有助于減少訪問對象或對象的成員時所需的工作量。類似地,對 OleDbDataAdapter 和 DataSet 對象進行聲明和初始化,分別代表數據庫與數據集之間的適配器以及數據集。OleDbAdapter 對象的 FillData 方法將數據庫中的數據復制到數據集。此代碼的核心是 ListData 子例程。
有關 ADO.NET 的更多信息,請參閱以下內容:
與以往一樣,請定期訪問 Office 開發人員中心(英文),以查找有關 Office 解決方案開發的信息和技術文章。
原文轉自:http://www.anti-gravitydesign.com