在 ADO 和 ADO.NET 中管理离线数据

转载 2006年06月02日 20:26:00

Carl Ganz, Jr.

*

在 VB6 中,OLE DB 游标服务允许您创建通常作为虚构的Recordset 的内容。这些只是 ADO Recordset 对象的内存中实例,Field 对象将添加到这些实例中以形成一个数据结构。您需要显式创建这些 Recordset 客户端,如清单 1 中所示;默认情况下,它们是在服务器端创建的,您在服务器上不能有离线 Recordset。

Set oRS = New ADODB.Recordset
oRS.CursorLocation = adUseClient
oRS.CursorType = adStatic
oRS.LockType = adLockBatchOptimistic
'Add a few fields
With oRS.Fields
.Append "LastName", adVarChar, 40, adFldIsNullable
.Append "FirstName", adVarChar, 40, adFldIsNullable
.Append "HireDate", adDate
End With
oRS.Open

一旦创建 Recordset,您就可以用数据填充它了。请注意,Field 集合的 Append 方法只能用于关闭的 Recordset;如果您在打开 Recordset 的 Fields 集合上或是已设置 ActiveConnection 属性的 Recordset 上调用 Append,就会导致运行时错误。清单 2 阐释了如何将数据添加到 Recordset 对象。

清单 2 中的最后两行代码阐释了如何创建索引,以使排序更加高效。(通常,您应通过一个提供初始排序的 SQL 命令来加载此类数据,但是如果数据在网格中,您可能希望允许用户通过(比如说)单击列标题来排序它。)

清单 2. 用数据填充 Recordset 对象。

'Populate with some data
oRS.AddNew Array("LastName", "FirstName", "HireDate")_
, Array("Washington", "George", "3/12/2003")
oRS.AddNew Array("LastName", "FirstName", "HireDate")_
, Array("Adams", "John", "8/5/2003")
oRS.AddNew Array("LastName", "FirstName", "HireDate")_
, Array("Jefferson", "Thomas", "4/27/2003")
oRS.Update
'Create an in-memory index
oRS.Fields("LastName").Properties("Optimize").Value _
= True
'Sort on first name
oRS.Sort = "FirstName"

创建 Recordset 的另一种方法涉及到离线 Recordset。这只是一个 Recordset 对象,它随后将连接到由于将 ActiveConnection 属性设置为 Nothing 而离线的服务器(请参见清单 3)。

清单 3. 创建离线 Recordset。

Dim objConnection As ADODB.Connection
Dim szSQL As String
Set objConnection = New ADODB.Connection
'Open a connection
objConnection.ConnectionString = "whatever"
objConnection.Open
'Instantiate a Recordset object...
Set oRS = New ADODB.Recordset
oRS.CursorLocation = adUseClient
oRS.CursorType = adOpenStatic
oRS.LockType = adLockBatchOptimistic
'...and set the ActiveConnection property
Set oRS.ActiveConnection = objConnection
szSQL = "SELECT LastName, FirstName " & _
"FROM Employees " & "ORDER BY LastName, FirstName"
'Open the Recordset and return the employee data
oRS.Open szSQL
Set oRS.ActiveConnection = Nothing
objConnection.Close
Set DataGrid1.DataSource = oRS

使用 ADO.NET

ADO.NET 为离线数据管理提供了更强大的功能。DataTable 和 DataSet 对象本身就定义为离线,因此您不必执行任何操作来使它们离线。从概念上来说,ADO.NET DataTable 对象和 ADO Recordset 对象的编程创建过程非常类似,如清单 4 中所示。在本示例中,我们要创建一个 DataTable 对象,并向其添加列和行对象。正如您将看到的那样,ADO.NET 的方法使用了一个比基于 COM 的 ADO 所使用的更加层次化的对象模型。

清单 4. 创建 ADO.NET DataTable 对象。

Dim oDataRow As DataRow
Dim oDataColumn As DataColumn
Dim aPrimaryKey(0) As DataColumn
oDS = New DataSet
'Create a new DataTable oect
oEmployeeDT = New DataTable
'Add an event handler for column data changes
AddHandler oEmployeeDT.ColumnChanged, _
New DataColumnChangeEventHandler(AddressOf _
ColumnChanged)
'Create primary key (PK) col and add it to the columns
'collection. Set init value to 1, increment as needed.
oDataColumn = New DataColumn
oDataColumn.ColumnName = "ID"
oDataColumn.DataType = _
System.Type.GetType("System.Int32")
oDataColumn.AutoIncrement = True
oDataColumn.AutoIncrementSeed = 1
oEmployeeDT.Columns.Add (oDataColumn)
'PK property receives array of DataColumn objects in
'case you have multi-col index. I prefer an ID column.
aPrimaryKey(0) = oDataColumn
oEmployeeDT.PrimaryKey = aPrimaryKey
'Create the individual data columns
…
oDataColumn = New DataColumn
oDataColumn.ColumnName = "Salary"
oDataColumn.DataType = _
System.Type.GetType("System.Decimal")
oEmployeeDT.Columns.Add (oDataColumn)
'Here we use DataColumn's Expression property to show
'what a 28% tax on the salary will amount to.
oDataColumn = New DataColumn
oDataColumn.ColumnName = "IncomeTax"
oDataColumn.DataType = _
System.Type.GetType("System.Decimal")
oDataColumn.Expression = "Salary * .28"
oEmployeeDT.Columns.Add (oDataColumn)
oDataColumn = New DataColumn
oDataColumn.ColumnName = "HireDate"
oDataColumn.DataType = _
System.Type.GetType("System.DateTime")
oEmployeeDT.Columns.Add (oDataColumn)
'This col receives the value calc'd by event handler
oDataColumn = New DataColumn
oDataColumn.ColumnName = "DaysSinceHire"
oDataColumn.DataType = _
System.Type.GetType("System.Int16")
oEmployeeDT.Columns.Add (oDataColumn)
'Once the columns are added, add sample data
oDataRow = oEmployeeDT.NewRow()
oDataRow("LastName") = "Washington"
oDataRow("FirstName") = "George"
oDataRow("Salary") = 45000
oDataRow("IncomeTax") = True
oDataRow("HireDate") = "4/12/1981"
oEmployeeDT.Rows.Add (oDataRow)
…
'Commit new data to the DataTable object and set
'RowState values of each row to Unchanged
oEmployeeDT.AcceptChanges()
'Let's show the user
DataGrid1.DataSource = oEmployeeDT

在实例化 DataTable 对象之后,您就可以使用这个事件模型将事件处理程序“DataColumnChangeEventHandler”设置为自定义例程。通过传递 ColumnChanged 例程的地址,只要一个列中的数据更改,您就可以执行这个处理程序。在本例中,我们要使用它来确定职员被雇佣以来的天数(请参见清单 5)。

清单 5. ColumnChanged 事件处理程序。

Sub ColumnChanged(ByVal sender As Object, _
ByVal e As DataColumnChangeEventArgs)
If e.Column.ColumnName = "HireDate" Then
e.Row("DaysSinceHire") = _
DateDiff(DateInterval.Day, _
e.Row("HireDate"), Date.Today)
End If
End Sub

由于用户在网格中编辑数据、添加和删除行,因此每个行对象的 RowState 属性会更改,以指示所作修改的类型。当用户将离线数据提交到 RDBMS 时,需要计算每一行来确定用户执行了何种类型的更改。要完成这一操作,您可以通过 GetChanges 方法检索包含所有新近添加、修改和删除的行的 DataTable 对象。然后,循环访问这个新 DataTable 中的每个行对象并计算 RowState 属性,如清单 6 中所示。

清单 6. 标识更改的行并保存更改。

Dim oDataRow As DataRow
Dim oChangeDT As DataTable
'Get DataTable with only changed rows
oChangeDT = oEmployeeDT.GetChanges()
'Save button s/b disabled until a change is made
If oChangeDT Is Nothing Then
Exit Sub
End If
'Loop thru changed rows, make db updates
For Each oDataRow In oChangeDT.Rows
Select Case oDataRow.RowState
Case DataRowState.Added
'Insert code here
Case DataRowState.Modified
'Update code here
Case DataRowState.Deleted
'Delete code here
End Select
Next
oChangeDT.Dispose()
oChangeDT = Nothing
oDataRow = Nothing
'Issue AcceptChanges method to reset RowState values
oEmployeeDT.AcceptChanges()

假定我们需要(比如说)以一对多 (1:M) 的关系使用多个表。因为数据是相关的,所以我们可以在一个单独的 DataTable 中管理该信息,并在 DataSet 对象的保护下维护两个 DataTable 之间的关系。在以下示例中,我们将为每个职员指定多种薪水,并在相关的网格控件中查看它们。通过使用 DataRelation 对象,我们可以在两个数据集之间创建一个内存中关系,并将 Employee 表的 ID 列用作主键 (PK),而将 Paycheck 表的 EmployeeID 列用作外键 (FK)。引用完整性 (RI) 原则告诉我们,当一个职员记录被删除时,所有关联的薪水数据也必须被删除。为了实施这个规则,我们可以设置一个 ForeignKeyConstraint 对象(请参见清单 7)。

清单 7. 设置数据关系。

Dim oDataRelation As DataRelation
Dim oParentColumn As DataColumn
Dim oChildColumn As DataColumn
Dim oForeignKeyConstraint As ForeignKeyConstraint
GetPaychecks()
'Manage both tables from within a DataSet object
oDS.Tables.Add (oEmployeeDT)
oDS.Tables.Add (oPayCheckDT)
'Retrieve PK, FK from the employee, paycheck tables
oParentColumn = oEmployeeDT.Columns("ID")
oChildColumn = oPayCheckDT.Columns("EmployeeID")
'Create DataRelation object to maintain relationship
oDataRelation = New DataRelation("EmployeePaycheck", _
oParentColumn, oChildColumn)
oDS.Relations.Add (oDataRelation)
'Create ForeignKeyConstraint obj. to enforce delete
oForeignKeyConstraint = New _
ForeignKeyConstraint(oParentColumn, oChildColumn)
oForeignKeyConstraint.DeleteRule = Rule.Cascade

实际上,本文只是粗浅地探讨了您在 VB6 和 .NET 中使用离线数据可以实现的操作。由于 Microsoft 的数据访问技术正趋向于广泛使用离线数据,因此了解如何使用离线数据对您未来的开发工作是至关重要的。

下载 408CARL1.ZIP

有关 Hardcore Visual Basic 和 Pinnacle Publishing 的详细信息,请访问其网站 http://www.pinpub.com/

注:这不是 Microsoft Corporation 的网站。Microsoft 对该网站的内容不承担责任。

本 文是从 Hardcore Visual Basic 2004 年 8 月号转载的。版权所有 2004,Pinnacle Publishing, Inc.(除非另行说明)。保留所有权利。Hardcore Visual Basic 是 Pinnacle Publishing, Inc. 独立发行的产品。未经 Pinnacle Publishing, Inc. 事先同意,不得以任何形式使用或复制本文的任何部分(评论文章中的简短引用除外)。要联系 Pinnacle Publishing, Inc.,请致电 1-800-788-1900。

ADO和ADO.NET的区别

不同点: 1.接口和基础不同: ADO:     接口:OLEDB    基于:COM技术 ADO.NET:  接口:自己的ADO.NET接口    基于:.NET体系架构 2...
  • YiQiJinBu
  • YiQiJinBu
  • 2013年11月04日 22:38
  • 1124

ADO.NET 概述

ADO.NET 是一种应用程序与数据源交互的 API,它支持的数据源包括数据库、文本文件、Excel 表格或者 XML 文件等。ADO.NET 封装在 System.Data 命名空间及其子命名空间(...
  • GongchuangSu
  • GongchuangSu
  • 2015年10月12日 18:18
  • 2025

在 ADO 和 ADO.NET 中管理离线数据

在 ADO 和 ADO.NET 中管理离线数据发布日期: 10/26/2004 | 更新日期: 10/26/2004Carl Ganz, Jr.您可以使用无数种方法在 VB6 和 VB.NET 中处理...
  • skyremember
  • skyremember
  • 2009年02月21日 11:28
  • 546

两种数据访问方式:从ADO 到ADO.NET

电脑最大的好处就是可以帮助人处理大量数据,由此离不开对数据库的访问,先看看最近在做ASP.NET例子的时候经常用到的ADO.NET的数据库访问方式。...
  • u010927640
  • u010927640
  • 2016年03月13日 17:17
  • 3279

关于ADO.NET数据库操作中的增删改查讲解

我们要连接数据库之后就要对它进行增删改查,这里我们就详细的分析一下吧。对于ADO.NET数据库操作Insert,Update,Delete等单向操作,对于插入、删除、修改等操作,由于是客户端应用程序向...
  • letIgo
  • letIgo
  • 2011年10月17日 15:59
  • 1171

VB.NET必知必会(ADO.NET篇)

ADO相信我们都不陌生,那么ADO.NET和ADO是一种东西吗?我们来详细的看一下ADO.NET。       ADO.NET的名称起源于ADO(ActiveX Data Objects),是一个广...
  • kanglix1an
  • kanglix1an
  • 2012年12月16日 18:51
  • 5087

ADO.NET中5大对象简介

ADO.NET
  • haiyan_cf
  • haiyan_cf
  • 2014年05月28日 17:20
  • 3773

SQL Server 数据类型映射 (ADO.NET)

原文:https://msdn.microsoft.com/zh-cn/library/cc716729.aspx SQL Server 和 .NET Framework 基于不同的类型系统...
  • Joyhen
  • Joyhen
  • 2015年05月12日 01:42
  • 1561

ADO 与ADO.NET两种数据访问方式区别。

1. ADO与ADO.NET简介   ADO与ADO.NET既有相似也有区别,他们都能够编写对数据库服务器中的数据进行访问和操作的应用程序,并且易于使用、高速度、低内存支出和占用磁盘空间较少,支持用...
  • lvjin110
  • lvjin110
  • 2013年09月06日 11:11
  • 1492

ado.net中,并发控制时与数据库的更新、同步

摘自MSDN: http://msdn.microsoft.com/zh-cn/library/cc438079(VS.71).aspx 原文还有例子,建议直接去MSDN看。介绍 ADO.NET 中的...
  • lanman
  • lanman
  • 2009年06月24日 10:00
  • 1471
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在 ADO 和 ADO.NET 中管理离线数据
举报原因:
原因补充:

(最多只允许输入30个字)