Tuesday, January 30, 2007

Object to DataTable

When I lay my hands on ASP.NET 2.0, I was thrilled to use Generics in the form of List( of T) and used it to create collections of my business objects. I was even more excited to use the ObjectDataSource control and bind it to a GridView. But when I tried sorting the GridView, I got a runtime error which said that sorting of List (of T) is not supported and suggested using a DataTable or DataSet! Googling for a few minutes, I learned that to enable sorting for my collection class (in this case a Generic List), I need to first create a custom collection and then implement the IComparable interface. And then, I had to setThe ObjectDataSource's SortExpression.

I was too lazy to do all this and also didn't want my code scattered in multiple events so I decided to write a bit of 'reflective' code to convert my List(of T) to a DataTable. All I had to do then is Databind the DataTable and let GridView handle sorting.

The class cList2Table has a method to convert your System.Generics.List(of T) to a DataTable. cList2Table takes a generic list as its constructor parameter and returns a DataTable when you call the GetTable() method.

Imports System.Reflection
Public Class cObjectToTable(Of T)
Dim objectCollection As List(Of T)
Public Sub New(ByVal objectCollection As List(Of T))
Me.objectCollection = objectCollection
End Sub
Public Function GetTable() As DataTable
Dim table As New DataTable
Dim objectType As Type = GetType(T)
Dim objectProperties As PropertyInfo() = objectType.GetProperties
'create a column for each property in the class
For Each propertyItem As PropertyInfo In objectProperties table.Columns.Add(New DataColumn(propertyItem.Name, propertyItem.PropertyType))
For Each item As T In objectCollection
'create a new row based on the table structure we just created Dim row As DataRow = table.NewRow()
'copy object data to the datarow
For Each propertyItem As PropertyInfo In objectProperties
row(propertyItem.Name) = propertyItem.GetValue(item, Nothing)
'add row to the table
Return table
End Function
End Class

Now I usually like to see schema in the GridView during design time,So I filled my typed DataSet with the following snippet of code.

Dim loTable As New dsSection.dtSectionDataTable