使用 ADO.NET 模拟 Recordset






4.70/5 (16投票s)
2004 年 10 月 2 日
3分钟阅读

192159

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