skip to Main Content

Convert List<T>/IEnumerable to DataTable/DataView

Greetings visitor from the year 2024! You can get the source code for this from my Github repo here. Thanks for visiting.

Here’s a method to convert a generic List<T> to a DataTable. This can be used with ObjectDataSource so you get automatic sorting, etc.

using statement: using System.Reflection;
...

/// <summary>
/// Convert a List{T} to a DataTable.
/// </summary>
public DataTable ToDataTable<T>(List<T> items)
{
    var tb = new DataTable(typeof (T).Name);

    PropertyInfo[] props = typeof (T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

    foreach (PropertyInfo prop in props)
    {
        Type t = GetCoreType(prop.PropertyType);
        tb.Columns.Add(prop.Name, t);
    }

    foreach (T item in items)
    {
        var values = new object[props.Length];

        for (int i = 0; i < props.Length; i++)
        {
            values[i] = props[i].GetValue(item, null);
        }

        tb.Rows.Add(values);
    }

    return tb;
}

/// <summary>
/// Determine of specified type is nullable
/// </summary>
public static bool IsNullable(Type t)
{
    return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
}

/// <summary>
/// Return underlying type if type is Nullable otherwise return the type
/// </summary>
public static Type GetCoreType(Type t)
{
    if (t != null && IsNullable(t))
    {
        if (!t.IsValueType)
        {
            return t;
        }
        else
        {
            return Nullable.GetUnderlyingType(t);
        }
    }
    else
    {
        return t;
    }
}

I occasionally blog about programming (.NET, Node.js, Java, PowerShell, React, Angular, JavaScript, etc), gadgets, etc. Follow me on Twitter for tips on those same topics. You can also find me on GitHub.

See About for more info.

This Post Has 26 Comments

  1. Very cool tip.. just used that to bind my grid to custom business object.
    was searching everywhere for a way to do this that supports sorting
    🙂

  2. I’ve written a small library myself to accomplish this task. It uses reflection only for the first time an object type is to be translated to a datatable. It emits a method that will do all the work translating an object type.

    Its blazing fast. You can find it here: http://code.google.com/p/modelshredder/

  3. I know Jeff Atwood may agree, but dude, using ‘var’ for all your declarations is annoying.

    Use it where appropriate, not as a vb/keyboard laziness.

    Otherwise, very nice.

  4. must include using statement: using System.Reflection;

    Also, I am getting an error when trying to implement:

    DataTable myTable = new DataTable(“CurrentTable”);
    myTable = ToDataTable(svc);

    It is: The type arguments for the method cannot be inferred. Not really sure what that means. Can you post an actual implementation using the method?

  5. Hi Coder

    You need to specify the type of the list items in the call. Example:

    var persons = new List<Person>();
    DataTable myTable = ToDataTable<Person>(persons);

    Mal:

    I agree w/ you… var shouldn’t be used indiscriminately. I just learned about it when I wrote this article though… so I had to use it everywhere 🙂

    Chinh

  6. I have a method as follows.
    List GetServicesForLayoutFields()

    can somebody suggest how can call the method ToDataTable(List items) to convert my above list to a datatable..
    Please suggest

  7. I need this code badly but when I use it in my code I get the following error:

    DataSet does not support System.Nullable

    and it is generated on the following line:

    table.Columns.Add(property.Name, property.PropertyType);

    My code is identical to yours and I use your method in my BLL method such as:

    [DataObjectMethod(DataObjectMethodType.Select, true)]
    public DataTable GetList(string sortExpression, int maximumRows, int startRowIndex)
    {
    var records = _dc.Products.OrderBy(p => p.ProductName).ToList();
    return ToDataTable(records);
    }

    If you have any suggestions please help… 🙂

  8. Hi Marko:

    I’ve fixed the code in the article to support nullable types. As the error message suggests, DataSets do not support nullable types. So the fix I put in is to use the non-nullable counterpart when I encounter nullable types.

    Chinh

  9. Dude!!! you are lifesaver.
    I’ve been trying to get this #@#$ thing to work for more than 5 hours.
    Thanks a lot!

  10. This is not working when I join two table with all columns selected.

    var productsQuery = (from p in db.Products
    join c in db.Categories
    on p.Category_Id equals c.Category_Id
    where p.Vendor_Code == VendorCode
    select new { p,c });

    DataTable dt = LinqToDataTable.ToDataTable(productsQuery.ToList());

    Please suggest what to do?

  11. That’s why I love reflection. Understanding what goes on inside an unknown object (late-binding) is one of the most powerful programming concepts. Thanks for this nice code snippet.

  12. Dear Chinh Do!

    I suggest a slightly revised version of your code. As a result, you can get a datatable from an IEnumerable with values of value type and strings.

    public static DataTable ToDataTable(IEnumerable input)
    {
    DataTable dt = new DataTable(typeof(T).Name);

    PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

    if (typeof(T).IsValueType || typeof(T) == typeof(System.String))
    {
    Type t = GetCoreType(typeof(T));
    dt.Columns.Add(typeof(T).Name+”C”, t);
    }
    else
    {
    foreach (PropertyInfo property in properties)
    {
    Type t = GetCoreType(property.PropertyType);
    dt.Columns.Add(property.Name, t);
    }
    }

    foreach (T item in input)
    {
    if (typeof(T).IsValueType || typeof(T) == typeof(System.String))
    {
    dt.Rows.Add(item);
    }
    else
    {
    object[] values = new object[properties.Length];
    for (int i = 0; i < properties.Length; i++)
    {
    values[i] = properties[i].GetValue(item, null);
    }
    dt.Rows.Add(values);
    }
    }
    return dt;
    }
    public static Type GetCoreType(Type t)
    {
    if (t != null && IsNullable(t))
    {
    if (!t.IsValueType) { return t; }
    else { return Nullable.GetUnderlyingType(t); }
    }
    else { return t; }
    }
    public static bool IsNullable(Type t)
    {
    return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable));
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top