Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Reflection to create a DataTable from a Class?

I've just learned about Generics and I'm wondering whether I can use it to dynamically build datatables from my classes.

Or I might be missing the point here. Here is my code, what I'm trying to do is create a datatable from my existing class and populate it. However I'm getting stuck in my thought process.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.Data;  namespace Generics {     public class Dog     {         public string Breed { get; set; }         public string Name { get; set; }         public int legs { get; set; }         public bool tail { get; set; }     }      class Program     {         public static DataTable CreateDataTable(Type animaltype)         {             DataTable return_Datatable = new DataTable();             foreach (PropertyInfo info in animaltype.GetProperties())             {                 return_Datatable.Columns.Add(new DataColumn(info.Name, info.PropertyType));             }             return return_Datatable;         }          static void Main(string[] args)         {             Dog Killer = new Dog();             Killer.Breed = "Maltese Poodle";             Killer.legs = 3;             Killer.tail = false;             Killer.Name = "Killer";              DataTable dogTable = new DataTable();             dogTable = CreateDataTable(Dog); //How do I continue from here?           }           } }     

Now At the DataTable point it errors. Also, being new to reflection and Generics, how will I actually populate the data with the Killer class?

like image 216
vwdewaal Avatar asked Sep 11 '13 16:09

vwdewaal


2 Answers

Building up on all the previous answers, here is a version that creates a DataTable from any collection:

public static DataTable CreateDataTable<T>(IEnumerable<T> list) {     Type type = typeof(T);     var properties = type.GetProperties();                DataTable dataTable = new DataTable();     dataTable.TableName = typeof(T).FullName;     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; } 
like image 84
David Airapetyan Avatar answered Oct 05 '22 21:10

David Airapetyan


Here is a more compact version of David's answer that is also an extension function. I've posted the code in a C# project on Github.

public static class Extensions {     public static DataTable ToDataTable<T>(this IEnumerable<T> self)     {         var properties = typeof(T).GetProperties();          var dataTable = new DataTable();         foreach (var info in properties)             dataTable.Columns.Add(info.Name, Nullable.GetUnderlyingType(info.PropertyType)                 ?? info.PropertyType);          foreach (var entity in self)             dataTable.Rows.Add(properties.Select(p => p.GetValue(entity)).ToArray());          return dataTable;     }      } 

I have found that this works very well in conjunction with code to write a DataTable to CSV.

like image 43
cdiggins Avatar answered Oct 05 '22 21:10

cdiggins