Click here to Skip to main content
15,881,172 members
Articles / Database Development / SQL Server
Article

Simulating Recordsets with ADO.NET

Rate me:
Please Sign up or sign in to vote.
4.70/5 (18 votes)
2 Oct 20043 min read 187.1K   1.4K   40   35
A proposed class to simulate the ADODB.Recordset behavior in .NET.

Introduction

As any .NET developer knows, the ADO.NET approach to data access is substantially different from the ADODB predecessor. First of all, because it is disconnected and mostly based on the DataSet concept (that involves a client-side data caching), while ADODB was normally used as a connected data access paradigm (with the exception of the so-called "disconnected recordsets"). The only way to use ADO.NET in a connected fashion is using objects like DataReader, Command, and Transaction, that are not so comfortable if you need to scroll a result set making updates to some data based on a row-oriented logic. This was a very common task when working with ADODB, and a lot of programmers coming from a Visual Studio 6.0 experience will miss the Recordset concept: being oriented to disconnected scenarios, ADO.NET currently doesn't support features like server-side cursors, and so it doesn't expose objects similar to the ADODB.Recordset that was very useful to implement row-based logics. Anyone prevents you from continuing to use the ADODB objects while programming on .NET, but if you want to avoid the COM interoperability overhead, this is not the right way.

In this article, I propose a class that simulates the behavior of an ADODB.Recordset on a Microsoft SQL Server 2000 database through the use of ADO.NET "connected objects" (Connection, Command, DataReader,...) and of server-side cursors directly implemented in T-SQL. The proposed class is developed for SQL Server 2000, but can be easily modified to work with other RDBMSs.

How the code works

The class I wrote is named Recordset and it tries to simulate the ADODB.Recordset in its main functionalities. Then, it exposes methods like Open(), Close(), MoveNext(), MovePrevious(), MoveFirst(), MoveLast(), Update() and so on (even if it doesn't currently expose an AddNew() method). To support navigation and random access to rows of a result set without caching data on the client, you need to use a scrollable server-side cursor; this cursor has to be and remain open for all the duration of the connected updates. That's why, behind the scenes of the Recordset.Open() method, a connection is open and a T-SQL cursor is created, based on a given SELECT expression:

VB
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()

The various movements inside the Recordset have their counterparts in the server-side T-SQL cursor, so it's not difficult to implement for the Recordset class the following methods:

MethodT-SQL equivalent
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

For the Recordset.Update() method, if we suppose the cursor being based on a single-table SELECT statement, we can think to code it as a T-SQL statement like the following:

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

In the same way (under the same single-table SELECT statement restriction), also the Recordset.Delete() method can be coded as:

SQL
DELETE table_name WHERE CURRENT OF crsr

Finally, the Recordset.Close() method has simply to execute some cleanup code (on the server-side cursor and on the open connection):

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

The sample application

A sample application has been written to show how to use the Recordset class.

Image 1

It connects to the Authors table of the famous database Pubs on the local SQL Server (if you want to use another SQL Server or you don't use the deprecated "blank" password for sa, please modify the value associated to the ConnectionString key in the App.config configuration file). The user interface of the sample application is self-explaining: each button simply tests the corresponding method of the Recordset class.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Technical Lead
Italy Italy
I was born in 1970.

My first computer experience dates back to early 80s, with a Sinclair ZX81.
From that time on, as many "friends" say, my IT-illness has increased year by year.

I graduated in Electronic Engineering and earned the following Microsoft certifications:
MCP, MCT, MCDBA, MCSD, MCAD, MCSD for .NET (early achiever).

I worked in IT as a developer, a teacher, a consultant, a technical writer, a technical leader.
IT knowledge applied to real life is my primary interest and focus.

Comments and Discussions

 
Questiongestione eccezioni Pin
Member 1196192819-Sep-15 5:28
Member 1196192819-Sep-15 5:28 
Questiongestione eccezioni Pin
Member 1196192819-Sep-15 5:28
Member 1196192819-Sep-15 5:28 
AnswerRe: gestione eccezioni Pin
Alberto Venditti22-Sep-15 1:36
Alberto Venditti22-Sep-15 1:36 
QuestionSimulate propertie Pin
Mariano Escriu19-May-14 5:34
professionalMariano Escriu19-May-14 5:34 
GeneralReg Connection Problem Pin
prabakarank25-Aug-09 19:03
prabakarank25-Aug-09 19:03 
GeneralRe: Reg Connection Problem Pin
Alberto Venditti30-Aug-09 22:34
Alberto Venditti30-Aug-09 22:34 
Hi.
Sorry but this article targets Microsoft SQL Server exclusively.

If you want to adopt the Recordset concept on a Microsoft Access database, my suggestion is to use Recordsets natively through ADODB.

Hope this helps.
AV
GeneralPlease answer me for a Error Pin
phowarso12-Sep-07 3:09
phowarso12-Sep-07 3:09 
GeneralRe: Please answer me for a Error Pin
Alberto Venditti12-Sep-07 5:51
Alberto Venditti12-Sep-07 5:51 
QuestionHow to Concatinate Two Recordsets in Visual C++6 Pin
alisolution11-May-07 19:53
alisolution11-May-07 19:53 
AnswerRe: How to Concatinate Two Recordsets in Visual C++6 Pin
Alberto Venditti14-May-07 0:33
Alberto Venditti14-May-07 0:33 
QuestionAccessing mdb files Pin
shekiman27-Nov-06 20:48
shekiman27-Nov-06 20:48 
AnswerRe: Accessing mdb files Pin
Alberto Venditti27-Nov-06 21:37
Alberto Venditti27-Nov-06 21:37 
GeneralAccesing MS ACCESS in remote machine Pin
hariram2820-Sep-06 6:46
hariram2820-Sep-06 6:46 
GeneralRe: Accesing MS ACCESS in remote machine Pin
Alberto Venditti21-Sep-06 3:25
Alberto Venditti21-Sep-06 3:25 
GeneralRe: Accesing MS ACCESS in remote machine Pin
hariram2821-Sep-06 7:25
hariram2821-Sep-06 7:25 
GeneralRe: Accesing MS ACCESS in remote machine Pin
Alberto Venditti22-Sep-06 4:59
Alberto Venditti22-Sep-06 4:59 
QuestionAddnew( ) method Pin
pgkdave29-Aug-06 3:56
pgkdave29-Aug-06 3:56 
GeneralMaking the sample work Pin
JeppeGHJHGJGJhg2-Jun-05 22:09
JeppeGHJHGJGJhg2-Jun-05 22:09 
GeneralRe: Making the sample work Pin
Anonymous5-Jun-05 8:16
Anonymous5-Jun-05 8:16 
GeneralRe: Making the sample work Pin
Anonymous5-Jun-05 19:26
Anonymous5-Jun-05 19:26 
QuestionHow make please help me Pin
akorolev1020-Oct-04 2:43
akorolev1020-Oct-04 2:43 
GeneralThis is fun and all, but is it advisable Pin
Eric the Half-a-Bee12-Oct-04 2:31
sussEric the Half-a-Bee12-Oct-04 2:31 
GeneralRe: This is fun and all, but is it advisable Pin
Alberto Venditti12-Oct-04 6:18
Alberto Venditti12-Oct-04 6:18 
GeneralRe: This is fun and all, but is it advisable Pin
Anonymous12-Oct-04 20:14
Anonymous12-Oct-04 20:14 
GeneralServer-side cursors give poor scalability Pin
Pete Appleton10-Oct-04 22:30
Pete Appleton10-Oct-04 22:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.