Friday, February 27, 2009

Convert a DataReader to DataTable in ASP.NET

Convert a DataReader to DataTable in ASP.NET

A DataReader is a read-only forward-only way of reading data. It is quiet fast when compared to fetching data using a DataSet. Infact internally, a DataSet uses a DataReader to populate itself. However at times, we need the best of both worlds. A dataset/datatable is extremely handy when it comes to binding it to a control like a GridView. So to make use of both the DataReader and DataTable in the same solution, we can fetch the data using a DataReader and then convert it to a DataTable and bind it to the control. In this article, we will explore how to do the conversion using two approaches; the first one, a direct method by using the DataTable.Load() and the second one, by manually converting a DataReader to a DataTable.

Step 1: Create a new ASP.NET application. Drag and drop two GridView controls to the page. We will fetch data from a DataReader into a DataTable and bind the DataTable to the GridView’s. Before moving ahead, add a web.config file to the project and add the following element.

<connectionStrings>

<addname="NorthwindConn"connectionString="Data Source=(local); Initial Catalog=Northwind; Integrated Security=true;"/>


</connectionStrings>

Step 2: Let us first see how to convert a DataReader to a DataTable using the easy way out. DataTable in ADO.NET 2.0 contains a Load() method which enables the DataTable to be filled using a IDataReader. This method is quiet handy when you need to quickly create a DataTable, without using a DataAdapter!! Let us see how.

C#

private void ConvertDateReadertoTableUsingLoad()


{

SqlConnection conn = null;

try

{

string connString = ConfigurationManager.ConnectionStrings["NorthwindConn"].ConnectionString;


conn = new SqlConnection(connString);

string query = "SELECT * FROM Customers";

SqlCommand cmd = new SqlCommand(query, conn);


conn.Open();

SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);

DataTable dt = new DataTable();


dt.Load(dr);

GridView1.DataSource = dt;

GridView1.DataBind();


}

catch (SqlException ex)


{

// handle error

}

catch (Exception ex)


{

// handle error

}

finally

{

conn.Close();


}

}

VB.NET

Private Sub ConvertDateReadertoTableUsingLoad()

Dim conn As SqlConnection = Nothing


Try

Dim connString As String = ConfigurationManager.ConnectionStrings("NorthwindConn").ConnectionString

conn = New SqlConnection(connString)


Dim query As String = "SELECT * FROM Customers"

Dim cmd As SqlCommand = New SqlCommand(query, conn)


conn.Open()

Dim dr As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)

Dim dt As DataTable = New DataTable()


dt.Load(dr)

GridView1.DataSource = dt

GridView1.DataBind()


Catch ex As SqlException


' handle error

Catch ex As Exception

' handle error

Finally


conn.Close()

End Try

End Sub

Note 1: If there is some existing data in the DataTable, the data coming from the DataReader is merged with the existing rows.


Note 2: If you need a DataReader back from a DataTable, use the DataTable.CreateDataReader() method.

Step 3: The method shown in the Step 2 was the easy way out. However, if for some reason(if you are not using ADO.NET 2.0), you would want to convert a DataReader to a DataTable ‘manually’, here’s the code. In the code below, a DataTable schema is created first using the GetSchemaTable() method of DataReader. The GetSchemaTable() returns a DataTable describing the column metadata of the IDataReader. Once done, we loop through the rows of the schema table and create a DataColumn object and set its properties. This DataColumn is also added to the List<> collection. We then read rows from the DataReader and populate the DataTable.

C#

private void ConvertDataReaderToTableManually()


{

SqlConnection conn = null;

try

{

string connString = ConfigurationManager.ConnectionStrings["NorthwindConn"].ConnectionString;


conn = new SqlConnection(connString);

string query = "SELECT * FROM Customers";

SqlCommand cmd = new SqlCommand(query, conn);


conn.Open();

SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);

DataTable dtSchema = dr.GetSchemaTable();

DataTable dt = new DataTable();


// You can also use an ArrayList instead of List<>

List<DataColumn> listCols = new List<DataColumn>();


if (dtSchema != null)


{

foreach (DataRow drow in dtSchema.Rows)

{


string columnName = System.Convert.ToString(drow["ColumnName"]);

DataColumn column = new DataColumn(columnName, (Type)(drow["DataType"]));


column.Unique = (bool)drow["IsUnique"];

column.AllowDBNull = (bool)drow["AllowDBNull"];

column.AutoIncrement = (bool)drow["IsAutoIncrement"];


listCols.Add(column);

dt.Columns.Add(column);

}

}


// Read rows from DataReader and populate the DataTable

while (dr.Read())


{

DataRow dataRow = dt.NewRow();

for (int i = 0; i < listCols.Count; i++)


{

dataRow[((DataColumn)listCols[i])] = dr[i];

}

dt.Rows.Add(dataRow);

}


GridView2.DataSource = dt;

GridView2.DataBind();

}

catch (SqlException ex)


{

// handle error

}

catch (Exception ex)


{

// handle error

}

finally

{

conn.Close();


}


}

VB.NET

Private Sub ConvertDataReaderToTableManually()

Dim conn As SqlConnection = Nothing


Try

Dim connString As String = ConfigurationManager.ConnectionStrings("NorthwindConn").ConnectionString

conn = New SqlConnection(connString)


Dim query As String = "SELECT * FROM Customers"

Dim cmd As SqlCommand = New SqlCommand(query, conn)


conn.Open()

Dim dr As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)

Dim dtSchema As DataTable = dr.GetSchemaTable()


Dim dt As DataTable = New DataTable()

' You can also use an ArrayList instead of List<>

Dim listCols As List(Of DataColumn) = New List(Of DataColumn)()



If Not dtSchema Is Nothing Then

For Each drow As DataRow In dtSchema.Rows


Dim columnName As String = System.Convert.ToString(drow("ColumnName"))

Dim column As DataColumn = New DataColumn(columnName, CType(drow("DataType"), Type))


column.Unique = CBool(drow("IsUnique"))

column.AllowDBNull = CBool(drow("AllowDBNull"))

column.AutoIncrement = CBool(drow("IsAutoIncrement"))

listCols.Add(column)


dt.Columns.Add(column)

Next drow

End If


' Read rows from DataReader and populate the DataTable


Do While dr.Read()

Dim dataRow As DataRow = dt.NewRow()

For i As Integer = 0 To listCols.Count - 1


dataRow((CType(listCols(i), DataColumn))) = dr(i)

Next i

dt.Rows.Add(dataRow)

Loop

GridView2.DataSource = dt


GridView2.DataBind()

Catch ex As SqlException

' handle error

Catch ex As Exception


' handle error

Finally

conn.Close()

End Try



Step 4: Call the two methods on the PageLoad()


C#

protected void Page_Load(object sender, EventArgs e)

{


ConvertDateReadertoTableUsingLoad();

ConvertDataReaderToTableManually();

}

VB.NET

Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)


ConvertDateReadertoTableUsingLoad()

ConvertDataReaderToTableManually()

End Sub

The DataTable.Load(IDataReader) is extremely handy when you want to quickly bind the data coming from a DataReader to a control like the GridView. The DataTable.Load() method has three overloads. We have explored one of them. I would encourage you to explore the other two over here.




I hope this article was useful and I thank you for viewing it

Source : http://www.dotnetcurry.com/ShowArticle.aspx?ID=143

Counter