Generic list to DataTable
Ok, I have to admit that I'm sitting on a WebForms project that is using datasets and DataTable
a lot as DataSource
to GridView
's for example. When using GridView
's in asp.net it's pretty nice to have DataTable
as DataSource
s since the sorting of data is included in the DataSource
object, as long as you don't needs paging than you have to take more things into consideration. However, we've decided to implement all the services to send list of objects instead of datasets, which I think is good, but we still want to use DataTable
's as DataSource
. So how do we achieve this? Easy I say, all you need is some basic knowledge in generics and reflection to write an extension for IList<T>
that creates a DataTable
based on the generic type T
. I ended up writing four methods; two public extension methods, one private extension method and one helper method:
public static class ListExtensions
{
public static DataTable ToDataTable<T>(this IList<T> list)
{
IList<PropertyInfo> properties = list.GetPropertiesOfObjectInList();
DataTable resultTable = CreateTable(properties);
foreach(var item in list)
{
var row = CreateRowFromItem<T>(resultTable, item);
resultTable.Rows.Add(row);
}
return resultTable;
}
private static DataTable CreateTable(IList<PropertyInfo> properties)
{
DataTable resultTable = new DataTable();
foreach (var property in properties)
{
resultTable.Columns.Add(property.Name, property.PropertyType);
}
return resultTable;
}
public static IList<PropertyInfo> GetPropertiesOfObjectInList<T>(this IList<T> list)
{
return typeof(T).GetProperties().ToList();
}
private static DataRow CreateRowFromItem<T>(DataTable resultTable, T item)
{
var row = resultTable.NewRow();
var properties = item.GetType().GetProperties().ToList();
foreach (var property in properties)
{
row[property.Name] = property.GetValue(item, null);
}
return row;
}
}
What they do are the following:
ToDataTable
takes anIList<T>
and creates theDataTable
with dataCreateTable
creates the actual table from anIList<T>
GetPropertiesOfObjectInList
gets the properties of the object of typeT
(you need that to create the table)CreateRowFromItem
takes the resulting table, so you can ask for the structure of a row, and the item you wish to add and creates aDataRow
object of the item
That's how you spicy up your old WebForms project :).