4

How do I can rewind a cursor of a DataReader to the beginning?

With one DataReader result I need to run two while loop, but those have to be from beginning. They are two iterations in one result set running a query once.

Example:

dr = command.ExecuteReader(cmd);

while (dr.Read()) { 
    // do some...
}

// rewind cursor here

while (dr.Read()) {
    // do another things...
}

I've looked into the DataReader docs and I've found nothing, so if it can't be possible with DataReader, I may change the class for one that fits this purpose.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
DontVoteMeDown
  • 21,122
  • 10
  • 69
  • 105

1 Answers1

3

You cannot (unless you execute the command again): it is a one-way stream. If you want to see the data more than once you'll have to buffer it in memory yourself, for example in a List<T> (for some T), or (yeuch) as a DataTable.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • There's no another class for doing that? – DontVoteMeDown Jan 25 '13 at 13:17
  • That adds code complexity, and the memory requirement for holding all the rows client-side. Might be worth it, but in many cases it's fine to run the query twice. – Andomar Jan 25 '13 at 13:18
  • @Andomar and I would say that in the vast majority of cases, the memory is trivial compared to the network / rdbms latency. – Marc Gravell Jan 25 '13 at 13:19
  • @DontVoteMeDown loading data into something you can query is trivial. Heck, with dapper it can be just `var data = conn.Query("some sql").ToList()`, which gives you `dynamic` access to columns, or `conn.Query("some sql").ToList()` if you are happy to define a `SomeType`. With `DataTable` it would be just `someTable.Load(reader)`. How is this work? – Marc Gravell Jan 25 '13 at 13:22
  • Agreed, "it depends". In many cases performance doesn't matter at all and the simplest solution is the best. – Andomar Jan 25 '13 at 13:22
  • Unfortunately, this method that runs those queryes may be fast, It will be called with some frequency. So performance is relevant. – DontVoteMeDown Jan 25 '13 at 13:26
  • @DontVoteMeDown then buffering it in memory for a moment is likely to be your best option. The other thing you could do is refactor the code so that you can do everything in one pass. – Marc Gravell Jan 25 '13 at 13:28
  • I'll try buffering then using `List` as you suggested. I'm afraid that I have no escape from that cause I'm depending on the data that let me no choices for doing that in one pass. Thank you anyway. – DontVoteMeDown Jan 25 '13 at 13:34
  • It worked. I've loaded the DataReader in a DataTable to have a parallel iteration. Worked fine. – DontVoteMeDown Jan 25 '13 at 17:52