Dataset Features in Asp .net 2.0 by azamsharp

Introduction:

We all have been using DataSet object to in one way or the other.
The most common use of the DataSet object is to populate web server controls. These controls usually include template server controls like Datagrid, DataList and Repeater. ASP.NET 2.0 comes with several new features for the DataSet, DataTable classes. In this article we will go over some of the new features of the DataSet and DataTables and how these features will benefit the developer to build more robust applications.

Merging Two DataTables:

Consider a situation in which you have two DataTable objects and you need to merge them. If you are using ASP.NET 1.X then this can be accomplished using the following code:

	// This method merges the two tables
	private void MergeDataTable()
	{
		DataTable dtOne = new DataTable("FirstTable");
		dtOne.Columns.Add("MyColumn");
		DataTable dtTwo = new DataTable("SecondTable");
		dtTwo.Columns.Add("MyColumn");
		for(int i=1;i<=10;i++)
		{
		DataRow row = dtOne.NewRow();
		row["MyColumn"] = "Data"+i;
		dtOne.Rows.Add(row);
		}
		for(int i=11;i<=20;i++)
		{
		DataRow row = dtTwo.NewRow();
		row["MyColumn"] = "Data"+i;
		dtTwo.Rows.Add(row);
		}

		DataSet ds = new DataSet();
		ds.Tables.Add(dtOne);
		ds.Merge(dtTwo);
		DataGrid1.DataSource = ds;
		DataGrid1.DataBind();
	}

Explanation of the Code:

In the code above I simply make an object of the DataTable class. Add one column to the DataTable and then ran a loop to populate the DataTable with some dummy data. I followed the same steps to create and populate the second DataTable. After populating the DataTables my next task is to merge both tables into one. In ASP.NET 1.X you achieve this by using a DataSet as the container and adding both one table to the DataSet and then using the merge method to merge another DataTable to the DataSet.

If you bind this DataSet to the DataGrid you will only see the contents of the first DataTable which in this case is dtOne. The reason is simple by default DataSet is set to the first table in its collection which in our case is dtOne.

Now, let’s see that how the same task of merging can be done when using the enhanced ASP.NET 2.0 DataSet object.

private void MergeDataTable()
{
	DataTable dtOne = new DataTable("MyFirstTable");
	dtOne.Columns.Add("Number");
	DataTable dtTwo = new DataTable("MySecondTable");
	dtTwo.Columns.Add("Number");
	// Populate the first table
	for (int i = 1; i <= 10; i++)
	{
	DataRow row = dtOne.NewRow();
	row["Number"] = "Data" + i;
	dtOne.Rows.Add(row);
	}

	// Populate the second table
	for (int i = 11; i <= 20; i++)
	{
	DataRow row = dtTwo.NewRow();
	row["Number"] = "Data" + i;
	dtTwo.Rows.Add(row);
	}

	// Now merge the two tables /* ONLY ONE LINE OF CODE COOL RIGHT! */
	dtOne.Merge(dtTwo);
	GridView1.DataSource = dtOne;
	GridView1.DataBind();
}

Explanation of the Code:

The code is pretty much the same as I did before the only difference is the third last line where I used DataTables merge method to merge another table. Merge method is a new method that is introduced in ASP.NET 2.0 DataSet object.

Merging Two DataTables with Different Schema:

I know you must be wondering that what will happen if you try to merge two DataTables with different schema. Well you can try it out and you will find out that it does not throw any exception. The columns that does not belong to other DataTables will be left blank and hence no entry will be made in those columns. Check out the code below to get the clear idea of merging DataTables with different schemas.

private void MergeWithDifferentSchema()
{
	DataTable dtOne = new DataTable("MyFirstTable");
	dtOne.Columns.Add("Name");
	dtOne.Columns.Add("Phone");
	DataTable dtTwo = new DataTable("MySecondTable");
	dtTwo.Columns.Add("Name");
	dtTwo.Columns.Add("Email");
	for (int i = 1; i <= 10; i++)
	{
	DataRow row = dtOne.NewRow();
	row["Name"] = "Customer" + i;
	row["Phone"] = "Phone" + i;
	dtOne.Rows.Add(row);
	}

	for (int i = 10; i <= 20; i++)
	{
	DataRow row = dtTwo.NewRow();
	row["Name"] = "Customer" + i;
	row["Email"] = "Email" + i;
	dtTwo.Rows.Add(row);
	}
	dtOne.Merge(dtTwo);
	GridView1.DataSource = dtOne;
	GridView1.DataBind();
}

Explanation of the Code:

In the above code I am making two DataTables each having a different schema. This means that DataTable dtOne has different columns from DataTable dtTwo. The merge is performed the same way using the Merge method of the DataTable object. The result is shown in the screen shot below:

 Dataset in asp .net 2.0

You can easily configure it so if two DataTables of different schemas are merged together an error will be generated.

try{
	dtOne.Merge(dtTwo, false, MissingSchemaAction.Error);
}
catch (Exception ex)
{
	Response.Write(ex.Message);
}

 Iterating DataTable using foreach loop:

Most of the time we need to iterate through the DataTable rows.

When using ASP.NET 1.X we used to write the following code to iterate through the DataTable.

private void UsingForEachLoop(){
	DataTable customerTable = GetDataTable();
	foreach (DataRow row in customerTable.Rows)
	{
		Response.Write(row["Name"] as String);
		Response.Write("<BR>");
	}
}

Explanation of the Code:

The above code is pretty simple. I am using a simple foreach loop to iterate through the collection of rows which are contained inside the DataTable object.

Now let’s see how the same thing can be done more efficiently using the ASP.NET 2.0.

private void IteratingDataTable(){
	DataTable customerTable = GetDataTable();
	DataTableReader dtReader = new DataTableReader(customerTable);
	while (dtReader.Read())
	{
		Response.Write( (string) dtReader["Name"]);
		Response.Write("<BR>");
	}
}

Explanation of the Code:

By looking at the code above the first thing that should come to your mind is the SqlDataReader object. And yes you are right, DataTableReader works pretty much the same way except that its disconnected from the database.

What is the advantage of using DataTableReader over foreach loop?

That’s a good question to ask. And this can be explained by a simple example. Consider a situation in which you are iterating through the DataTable object and at one point you want to insert a new row in the DataTable. Writing code for this scenario is pretty straight forward. Check out the code below:

private void UsingForEachLoop(){
	DataTable customerTable = GetDataTable();
	foreach (DataRow row in customerTable.Rows)
	{
		Response.Write(row["Name"] as String);
		Response.Write("<BR>");
		// Cannot add like this: Collection cannot be modified
		AddRow(customerTable);
	}
}

private void AddRow(DataTable dt)
{
	if (counter == 0)
	{
		DataRow row = dt.NewRow();
		row["Name"] = "AzamSharp";
		dt.Rows.Add(row);
		counter++;
	}
}

The above code will throw an exception saying that Enumeration was alerted and it cannot be changed. This happens because you are adding the row to the DataTable while the iteration of the DataTable is in progress.

You can achieve this using DataTableReader object which let’s you add a new row and magically it also knows that the new row has been added and hence it reads the new row.

private void IteratingDataTable(){
	DataTable customerTable = GetDataTable();
	DataTableReader dtReader = new DataTableReader(customerTable);
	while (dtReader.Read())
	{
		Response.Write( (string) dtReader["Name"]);
		Response.Write("<BR>");
		// AddRow simply adds a ONLY ONE ROW and ends
		AddRow(customerTable);
	}
}

private void AddRow(DataTable dt)
{
	if (counter == 0)
	{
		DataRow row = dt.NewRow();
		row["Name"] = "AzamSharp";
		dt.Rows.Add(row);
		counter++;
	}
}

Serialization of DataSets: 

For all those people who are passing DataSets through webservices or remoting the objects there is good news. DataSet class now include binary serialization which means that the data passed will be in the compressed and also stored in the compressed binary form. Take a look at the example below which uses xml as well as binary serialization techniques.

//Serialization Format
private void DataSetSerialization()
{
	string xmlFileName = @"C:ServerFolderMyFile.xml";
	string binaryFileName = @"C:ServerFolderMyFile.dat";
	DataSet ds = GetDataSet();
	ds.RemotingFormat = SerializationFormat.Binary;
	IFormatter formatter = new BinaryFormatter();
	using (Stream output = new FileStream(binaryFileName, FileMode.Create, FileAccess.Write, FileShare.None))
	{
	// serialize dataset and write to disk
	formatter.Serialize(output, ds);
	}
}

DataSet class introduces a new property RemotingFormat which can be used to set up the type of Serialization Format. Its a better idea to use binary serialization when you have more rows like more than 100 in that case you will see the true benefit and the performance difference between the two types of serialization techniques.

I hope you liked the article, happy coding.