New Dataset Features In ADO.Net 2.0

Introduction

ADO.NET class libraries are used for accessing data from a wide range of data sources. One of the best features of ADO.Net is DataSet. Even though it was an exciting feature, performance was a concern with DataSet. Changes made to DataSet in ADO.Net 2.0 are mainly from a performance perspective. There are several changes made to the DataSet class to achieve higher performance. These improvements are primarily because of the New Indexing Engine and binary serialization option. In the later part of this article, we will discuss the changes to the DataTable class, which is more independent in ADO.Net 2.0, unlike previous versions. Now DataTable supports many XML features that were only available to DataSet in the earlier versions, i.e., ReadXML, ReadXMLSchema, WriteXML, Write XMLSchema, etc. It can also be serialized independently, like a DataSet.

Performance

DataSet is slow in general; in framework 2.0, many new enhancements are done to achieve better performance. Some of these changes are the New Indexing Engine and binary serialization option. The new indexing engine performs much faster data manipulation, i.e., inserts update, etc. This ensures better performance while filling and Merge operations.

In Framework 1.1, the only remoting option available for DataSet was XML serialization which was verbose and resulted in sluggish performance. Framework 2.0 allows programmers to assign formatting options for a DataSet as well as a DataTable to binary or xml by setting the RemotingFormat property as shown below.

// Set the RemotingFormat to Binary serialization
ds.RemotingFormat = SerializationFormat.Binary;
// Set the RemotingFormat to XML serialization
ds.RemotingFormat = SerializationFormat.Xml;

By default, the RemotingFormat property is set to SerializationFormat.Xml. If you look closely at the DataSet class, it implements an ISerializable interface. This is a simple interface with just a single method, as shown below.

/// <summary>
/// Populates a SerializationInfo object with the data needed to serialize the object.
/// </summary>
/// <param name="info">The SerializationInfo to populate with data.</param>
/// <param name="context">The destination (StreamingContext) for this serialization.</param>
void GetObjectData(SerializationInfo info, StreamingContext context);

Now in Framework 2.0, while implementing the GetObjectData method, the DataSet class will use the RemotingFormat Property as well as shown below.

/// <summary>
/// Implements the ISerializable interface to populate a SerializationInfo object 
/// with the data needed to serialize the object.
/// </summary>
/// <param name="info">The SerializationInfo to populate with data.</param>
/// <param name="context">The destination (StreamingContext) for this serialization.</param>
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
    // Get the RemotingFormat of the current object
    SerializationFormat format = this.RemotingFormat;
    // Serialize the DataSet with the specified format
    this.SerializeDataSet(info, context, format);
}

SerializeDataSet is a private method implemented by DataSet to populate the SerializationInfo memory buffer with data.

/// <summary>
/// Serializes the DataSet object based on the specified SerializationFormat.
/// </summary>
/// <param name="info">The SerializationInfo to populate with data.</param>
/// <param name="context">The destination (StreamingContext) for this serialization.</param>
/// <param name="remotingFormat">The SerializationFormat to be used for serialization.</param>
private void SerializeDataSet(SerializationInfo info, StreamingContext context, SerializationFormat remotingFormat)
{
    // Implementation of DataSet serialization based on the specified format goes here
    // ...
}

Binary Serialization provides an enormous improvement in terms of performance, and the gain is more significant when we deal with a larger dataset (with a large number of rows). The following diagram illustrates the same fact.

binary serialization

New and Much Improved DataTable

DataTable was definitely one of the key classes in ADO.net APIs; however, it had a limitation that it was dependent on the parent DataSet class it is associated with. Whenever programmers were required to work with DataTable, they had to assign the parent DataSet as well. In Framework 2.0, DataTable is an independent entity. It supports all basic XML-related functionality provided by the DataSet, like ReadXML, ReadXMLSchema, WriteXML, WriteXMLSchema, etc. Also, now DataTable can be serialized independently using the RemotingFormat property explained in the Performance section.

Another new addition in Framework 2.0 is the Load Method.

DataTable can be loaded using the IDataReader object as described below.

// Create a new DataTable instance
DataTable dt = new DataTable();
// Load data into the DataTable from a data reader (assuming `reader` is a valid DataReader object)
dt.Load(reader);

The Load method also supports other overloads that accept LoadOption, as described below.

// Load data into the DataTable from a data reader, overwriting any existing changes
dt.Load(reader, LoadOption.OverwriteChanges);

The LoadOption enum has two other options, i.e., PreserveChanges and Upsert. There is one more overload for the Load method, which also allows the programmer to specify the FillErrorEventHandler delegate to be called when an error occurs while loading data.

DataTable also provides a new method for creating a DataTableReader, as described below.

// Create a DataTableReader from an existing DataTable (`dt`)
DataTableReader dtReader = dt.CreateDataReader();

Please note that the DataTableReader class derives from DbDataReader.

/// <summary>
/// Custom implementation of a data reader for DataTable objects.
/// </summary>
public sealed class DataTableReader : DbDataReader
{
    // Class implementation goes here
}

CreateDataReader method of DataTable makes it easy for programmers who require data not in the DataTable but in a DataReader object. Load and CreateDataReader method can be used to exchange data between DataTable and DataReader.


Similar Articles