DataSet Vs. DataReader Article

I like to do as little work as I can when I code, so I used to like the DataSet. It can be filled and ready to go in just 3 lines of code, and then iterated using a nice, simple foreach loop (it’s even easier if you use typed DataSets!). It’s a nice collection to work with. But often, performance is required at the expense of elegance — especially on a performance-critical Web application.

The DataSet actually uses a DataReader to populate itself. A DataReader is a lean, mean access method that returns results as soon as they’re available, rather than waiting for the whole of the query to be populated into a DataSet. This can boost your application performance quite dramatically, and, once you get used to the methodology, can be quite elegant in itself.

The Advantages of DataReader in Action

To highlight the advantages of using a DataReader over the DataSet, here’s an example of using a DataSet. The following fills a DataSet with the results from a table, and outputs the first field in each row:

  SqlConnection conn = new SqlConnection(connectionString); 
 SqlDataAdapter a = new SqlDataAdapter
("select * from mytable;",conn);
 DataSet s = new DataSet();
 a.Fill(s);
 foreach (DataRow dr in s.Tables[0].Rows)
 {
   Console.WriteLine(dr[0].ToString());
 }

As you can see, we don’t actually start the actual inspection of data (the foreach loop), until the whole DataSet has been filled. There may be occasions where we may not use all our results, or we might execute other code while inspecting (a progress bar’s progress is a trivial example). Using a DataSet, this can only take place after the complete results are fetched and passed into the various collections within the DataSet.

In contrast, here’s code that achieves the same results using a DataReader in place of a DataSet:

  SqlConnection conn = new SqlConnection(connectionString); 
 SqlCommand comm = new SqlCommand("select * from mytable", conn);
 comm.Connection.Open();
 SqlDataReader r =  
     comm.ExecuteReader(CommandBehavior.CloseConnection);
 while(r.Read())  
 {
   Console.WriteLine(r.GetString(0));
 }
 r.Close();
 conn.Close();

Here, the inspection is made as soon as data is available by employing the while loop, where r.Read() returns false if no more results are found. Not only can we therefore inspect as we go, but the DataReader only stores one result at a time on the client. This results in a significant reduction in memory usage and system resources when compared to the DataSet, where the whole query is stored.

When Only DataSet Will Suffice

Now, there are times when only a DataSet will suffice. Often, you’ll need to serialize your results, or pass the query results on to the next tier of your application. In these cases, a collection is required, and the DataSet provides a well-supported mechanism for doing this. For example, you can quickly serialize a DataSet to XML by calling the WriteXML method, or pass a DataSet in a SOAP method. While you can create your own collections to store your results, with all this in-built, optimized functionality at hand, the DataSet is still a powerful type to keep in mind.

However, for the majority of queries employed by Web applications, where data is found, displayed, and then forgotten, the DataReader will increase your performance drastically, with only a little extra work. Sounds like a good deal to me!

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Sanjay Solanki

    Good Site, Good Article !

  • Faisal

    Try to include simple coding in examples