分享
 
 
 

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

王朝c#·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

您可以使用无数种方法在 VB6 和 VB.NET 中处理数据。这两个平台都支持诸如数组和集合之类的结构,开发人员通常将自定义类包装到这些结构中,就如您在 Carl Ganz 2004 年 3 月的专栏中看到的那样。数据独立(这可能是创建自定义数据抽象层的最大优势)允许用户在独立于数据库的情况下操作数据。这不仅降低了服务器的负担,还消除了维护到该数据库的开放连接的需要,或是对忘记更新 RDBMS 的担心。本月,Carl 将分析如何同时使用 ADO 和 ADO.NET 来创建此类数据对象。

在 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

a?

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)

a?

'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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有