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))
        Next
    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)
            Next
        'add row to the table
            table.Rows.Add(row)
        Next
    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
loTable.Load(loObject2Table.GetTable().CreateDataReader)