Udemy

How to Convert List to DataTable in C#

Wednesday, March 18, 2015 0 Comments A+ a-

Sometimes we have scenario where we need to make a DataTable from a List of some type.Normally what comes in mind is that create a DataTable, create columns that are in that type  and iterate on list items and add rows one by one, which is surely needed here.

A normal approach used is like:


List<SomeType> list = new List<SomeType>();

DataTable dt = new DataTable();

PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(SomeType));

foreach (var prop in props)
{
 dt.Columns.Add(prop.Name,prop.PropertyType);
}


and now iterate on List and add row one by one:


foreach (var item in list)
{
 dt.Rows.Add(item.Property1,item.Property2);
}


But there is another way which is much better using Generics and Reflection , and which will work for any type of List.

Though the above code will work, but think if we have 50 classes in project and we have List of each type do every time when we want data-table against any type of List from them then we have to write every time the above code for each type of List which is code redundancy and its against DRY(Do not Repeat Yourself).


Now consider this solution using Generics and Reflection. It is an  Extension Method on type List<T> . You can read more about Extension Methods in detail from here:


public static class ListExtensions
{
   public static DataTable ToDataTable<T>(this List<T> iList)
   {
    DataTable dataTable = new DataTable();
    PropertyDescriptorCollection propertyDescriptorCollection =
        TypeDescriptor.GetProperties(typeof(T));
    for (int i = 0; i < propertyDescriptorCollection.Count; i++)
    {
        PropertyDescriptor propertyDescriptor = propertyDescriptorCollection[i];
        Type type = propertyDescriptor.PropertyType;

        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
            type = Nullable.GetUnderlyingType(type);


        dataTable.Columns.Add(propertyDescriptor.Name, type);
    }
    object[] values = new object[propertyDescriptorCollection.Count];
    foreach (T iListItem in iList)
    {
        for (int i = 0; i < values.Length; i++)
        {
            values[i] = propertyDescriptorCollection[i].GetValue(iListItem);
        }
        dataTable.Rows.Add(values);
    }
    return dataTable;
  }
}

Now you just need to call it on any object type of List<T> and it will return DataTable against that List<T>.

This is how to use it:


List<SomeType> list = new List<SomeType>();

DataTable dt = users.ToDataTable();

Enough for today.
Coursera - Hundreds of Specializations and courses in business, computer science, data science, and more