Home > Articles

Working with DataSets

  • Print
  • + Share This
This chapter is from the book

Yesterday you walked through an end-to-end example of building an ASP.NET application designed to put the use of ADO.NET in perspective. However, the reliance on code-generating wizards can certainly obscure the breadth of functionality that is at your disposal. For that reason, today and the next four days will be devoted to an in-depth look at all aspects of the DataSet object. Unlike yesterday, the format of the next few days will not take you through an application or work with graphical tools, but rather will examine short snippets and code listings that highlight specific features and behaviors of the DataSet. Specifically, today you will learn the most common techniques for working with DataSet objects, including

  • How a DataSet compares to an ADO Recordset

  • How to programmatically populate and traverse a DataSet

  • How to select and find rows within a table

  • How to copy, clone, and merge DataSet objects

  • How to be notified of events

  • The importance and use of a DataView

Understanding the ADO.NET DataSet

The DataSet class is a member of the System.Data namespace. It represents the first of the two major components of the ADO.NET architecture you learned about on Day 1, "ADO.NET In Perspective," the other being the .NET Data Providers. Its major attributes include the following:

  • It is XML-based.

  • It is an in-memory cache of data that is not backed by a file or data store—it is disconnected.

  • It is independent of a data store and cannot communicate with one by itself.

  • It can store data in multiple tables from multiple data stores that can be related through foreign key relationships.

  • It stores multiple versions of the data for each column and for each row in each table.

  • It can be serialized with full fidelity to XML for transport between tiers of a distributed application even when those tiers reside on separate physical machines.

As is evident from this list, the DataSet provides the core object for building applications using a disconnected programming model. ADO.NET also supports a connected model for data retrieval through the use of the data readers, as you'll learn on Day 11, "Using a DataReader."

This list should also point to several of the similarities and differences between the DataSet and the Recordset object available in ADO that might be helpful if you are experienced with ADO. Similar to the DataSet, a Recordset could be disconnected from its data store and therefore act as an in-memory cache of data. Of course, it could also be used in a connected model depending on the cursor options that were set. Although the Recordset object stored multiple versions of each column for each of its rows, it was not by nature able to represent multiple tables without the use of the Data Shape Provider. The Recordset was not XML-based and could not be serialized to XML easily or flexibly. Finally, a Recordset was not independent of a data store because it tracked a Connection object and through its methods could send queries to the data source to populate, update, and refresh its data. To that end, the Recordset contained functionality found in the ADO.NET DataSet, data reader, and data adapter objects.

The DataSet class itself is derived from the class System.ComponentModel.MarshalByValueComponent, from which it receives its ability to be serialized, added to the VS .NET toolbox, and visually designed in a designer. Its place in the .NET Framework is shown in Figure 3.1.

Figure 3.1Figure 3.1 The DataSet in context within the .NET Framework. Note that all objects are ultimately derived from System.Object and that namespaces are denoted with dotted borders.

The major properties, methods, and events (collectively referred to as members) of the DataSet class can be seen in Table 3.1.

Table 3.1 Important DataSet Members





Property that gets or sets whether string comparisons are case sensitive


Property that gets or sets the name of the DataSet


Property that gets a custom view of data to allow searching, sorting, and filtering


Property that specifies whether constraint rules are followed when updates occur


A collection of custom information that resides with the DataSet


Property that indicates whether there are errors in any rows in any of the tables


Property that gets or sets an XML namespace for the DataSet


Property that gets or sets an XML prefix for the namespace for the DataSet



A collection of relations housed in a DataRelationCollection object that link tables through foreign keys


A collection of tables (DataTable objects exposed through a DataTableCollection object) that store the actual data



Method that commits all changes to the DataSet


Method that removes all rows from all tables


Method that copies the structure but no data from the DataSet


Method that copies both the structure and data of a DataSet


Method that returns a copy of the DataSet with only changed rows or those that match a given DataRowState filter


Method that returns an XML representation of the data


Method that returns an XML representation of the structure of the DataSet


Method that returns a value indicating that there are pending changes


Method that infers the structure of the DataSet based on a file or stream


Method that merges this DataSet with one provided


Method that loads an XML schema and data into a DataSet


Method that loads an XML schema into a DataSet


Method that rolls back all changes made to a DataSet (opposite of AcceptChanges)


Method that reverts the DataSet to its original state


Method that writes XML data and optionally the schema to a file or stream


Method that writes the XML schema to a file or stream


Method that writes the XML schema to a file or stream



Event that fires when a merge fails due to constraint violations

Throughout the next several days, you'll become very familiar with these members and how they can be used in your applications. Keep in mind that through overloading, many of the methods shown in Table 3.1 can accept different sets of arguments and therefore work in several different ways.

  • + Share This
  • 🔖 Save To Your Account