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?
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; }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With