Search code examples
c#entity-frameworkdatatable

Take EF Model and Convert it to Datatable?


I have a EF core model that I need to convert to a data table but I don't want to manually map it my self if possible.

I found this code in a stack answer

 private static DataTable CreateDataTable<T>(IEnumerable<T> list)
        {
            Type type = typeof(T);
            var properties = type.GetProperties();

            DataTable dataTable = new DataTable();
            foreach (PropertyInfo info in properties)
            {

                dataTable.Columns.Add(new DataColumn(info.Name, Nullable.GetUnderlyingType(info.PropertyType) ?? info.PropertyType));
            }

            foreach (T entity in list)
            {
                object[] values = new object[properties.Length];
                for (int i = 0; i < properties.Length; i++)
                {
                    values[i] = properties[i].GetValue(entity);
                }

                dataTable.Rows.Add(values);
            }

            return dataTable;
        }

however I have properties that of course reference other classes and I think they are being picked up as I get an error like this.

The type of column 'Category' is not supported.  The type is 'Category'

Solution

  • You can go with:

    List<PropertyInfo> properties = new List<PropertyInfo>();
    
    foreach (PropertyInfo info in type.GetProperties())
    {
        if (info.PropertyType.IsValueType || info.PropertyType == typeof(string))
        {
             dataTable.Columns.Add(new DataColumn(info.Name, Nullable.GetUnderlyingType(info.PropertyType) ?? info.PropertyType));
             properties.Add(info);
        }
    }
    foreach (T entity in list)
    {
         int i = 0;
         object[] values = new object[properties.Count];
         foreach (PropertyInfo info in properties)
         {
             values[i] = properties[i].GetValue(entity);
             i++;
         }
    
         dataTable.Rows.Add(values);
    }
    

    This same foreach you can use on the properties, so remove the for loop..