65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 ADO.NET 模拟 Recordset

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.70/5 (16投票s)

2004 年 10 月 2 日

3分钟阅读

viewsIcon

192159

downloadIcon

1403

.NET 中模拟 ADODB.Recordset 行为的类。

引言

众所周知,.NET 开发者都知道,ADO.NET 的数据访问方法与之前的 ADODB 有很大不同。首先,是因为它**断开连接**,并且主要基于 DataSet 概念(涉及客户端数据缓存),而 ADODB 通常用作**连接**数据访问范式(除了所谓的“断开连接的 recordset”)。使用 ADO.NET 进行连接访问的唯一方法是使用 DataReaderCommandTransaction 等对象,如果您需要滚动结果集并在基于行操作的逻辑上更新某些数据,这些对象并不那么方便。这在处理 ADODB 时是一个非常常见的任务,许多来自 Visual Studio 6.0 经验的程序员会怀念 Recordset 的概念:由于面向断开连接的场景,ADO.NET 目前不支持服务器端游标等功能,因此它不公开与 ADODB.Recordset 类似的对象的 ADODB.Recordset,后者在实现基于行的逻辑方面非常有用。没有人阻止您在 .NET 中进行编程时继续使用 ADODB 对象,但如果您想避免 COM 互操作的开销,这不是正确的方法。

在本文中,我提出了一个类,该类通过使用 ADO.NET 的“连接对象”(ConnectionCommandDataReader 等)以及 T-SQL 中直接实现的服务器端游标,来模拟 Microsoft SQL Server 2000 数据库的 ADODB.Recordset 的行为。提出的类是为 SQL Server 2000 开发的,但可以轻松修改以与其他 RDBMS 一起使用。

代码工作原理

我编写的类名为 Recordset,它试图在其主要功能中模拟 ADODB.Recordset。然后,它公开了 Open()Close()MoveNext()MovePrevious()MoveFirst()MoveLast()Update() 等方法(尽管它目前没有公开 AddNew() 方法)。要支持导航和随机访问结果集中的行而不缓存客户端数据,您需要使用可滚动服务器端游标;此游标必须并且将保持打开状态,直到连接更新完成。这就是为什么在 Recordset.Open() 方法的后台,会打开一个连接,并基于给定的 SELECT 表达式创建一个 T-SQL 游标。

cnn = New SqlConnection(mConnectionString)
cmd = cnn.CreateCommand()
cnn.Open()
...
cmd.CommandText = "DECLARE crsr SCROLL CURSOR FOR " & mSelectString
cmd.ExecuteNonQuery()
cmd.CommandText = "OPEN crsr"
cmd.ExecuteNonQuery()

Recordset 中的各种移动操作在服务器端的 T-SQL 游标中有相应的操作,因此为 Recordset 类实现以下方法并不困难:

方法 T-SQL 等效项
MoveNext() FETCH NEXT FROM crsr
MovePrevious() FETCH PRIOR FROM crsr
MoveFirst() FETCH FIRST FROM crsr
MoveLast() FETCH LAST FROM crsr
MoveAbsolute(n) FETCH ABSOLUTE n FROM crsr
MoveRelative(n) FETCH RELATIVE n FROM crsr

对于 Recordset.Update() 方法,如果我们假设游标基于单个表的 SELECT 语句,我们可以将其编码为如下 T-SQL 语句:

UPDATE table_name
SET field1=value1, field2=value2,...
WHERE CURRENT OF crsr

同样(在相同的单表 SELECT 语句限制下),Recordset.Delete() 方法也可以编码为:

DELETE table_name WHERE CURRENT OF crsr

最后,Recordset.Close() 方法只需执行一些清理代码(针对服务器端游标和打开的连接)。

cmd.CommandText = "CLOSE crsr"
cmd.ExecuteNonQuery()
cmd.CommandText = "DEALLOCATE crsr"
cmd.ExecuteNonQuery()
cmd.Dispose()
cnn.Close()
cnn.Dispose()

示例应用程序

已编写了一个示例应用程序来演示如何使用 Recordset 类。

它连接到著名的 Pubs 数据库的 Authors 表,该数据库位于本地 SQL Server 上(如果您想使用另一个 SQL Server 或不使用已弃用的 sa 用户的“空白”密码,请修改 App.config 配置文件中与 ConnectionString 键关联的值)。示例应用程序的用户界面不言自明:每个按钮都简单地测试 Recordset 类的相应方法。

© . All rights reserved.