c# - create a datatable from a class (not a list of instances)
This question concerns generics and types as well as datatables.
The following snippet is around the net here and there, and creates a datatable based on a generic type:
public static DataTable ListToDataTable<T>(List<T> list)
{
DataTable dt = new DataTable();
foreach (PropertyInfo info in typeof(T).GetProperties())
{
dt.Columns.Add(new DataColumn(info.Name, info.PropertyType));
}
foreach (T t in list)
{
DataRow row = dt.NewRow();
foreach (PropertyInfo info in typeof(T).GetProperties())
开发者_Go百科 {
row[info.Name] = info.GetValue(t, null);
}
dt.Rows.Add(row);
}
return dt;
}
I'm using the excellent FileHelpers library to import batches of records into SQL Server. To use SqlBulkCopy I need a datatable with columns from a given type. Filehelpers can read in a .cs file at runtime and create your type based on that. eg:
System.Type userType = null;
userType = ClassBuilder.ClassFromSourceFile("myclassfile.cs");
I'd like to change the method above so it just creates the columns for me when passed a type (eg 'userType'). ie the method signature would be something like:
public static DataTable TypeToDataTable<T>(<T> myType)
and would return an empty dataset with columns, ready to have rows of userType added to it.
I've tried various methods - any ideas?
It's actually pretty simple, when you realize that you don't need to (or even can) use generics in this case:
public static DataTable CreateEmptyDataTable(Type myType)
{
DataTable dt = new DataTable();
foreach (PropertyInfo info in myType.GetProperties())
{
dt.Columns.Add(new DataColumn(info.Name, info.PropertyType));
}
return dt;
}
You would call it like this:
System.Type userType = null;
userType = ClassBuilder.ClassFromSourceFile("myclassfile.cs");
DataTable emptyDataTable = CreateEmptyDataTable(userType);
Recently I needed exactly this and found it here on SO. I combined the premise in the question with the answer and decided to share the code since both are incomplete:
private DataTable CreateDataTableFromObjects<T>(List<T> items, string name = null)
{
var myType = typeof(T);
if (name == null)
{
name = myType.Name;
}
DataTable dt = new DataTable(name);
foreach (PropertyInfo info in myType.GetProperties())
{
dt.Columns.Add(new DataColumn(info.Name, info.PropertyType));
}
foreach (var item in items)
{
DataRow dr = dt.NewRow();
foreach (PropertyInfo info in myType.GetProperties())
{
dr[info.Name] = info.GetValue(item);
}
dt.Rows.Add(dr);
}
return dt;
}
精彩评论