Just as you used Reflection
to retrieve generic type properties, you can also use Reflection
to retrieve the property value for an instance of that type, it would look like this:
protected virtual DataTable buildDataTableFromComplexTypeList<T>(string tableName, List<T> complexList)
{
DataTable dataTable = new DataTable(tableName);
PropertyInfo[] properties = typeof(T).GetProperties(); // Getting the metadata through reflection (System.Reflection)
foreach (PropertyInfo property in properties) // Create DataTableColumns from the T properties
{
var type = (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) ? Nullable.GetUnderlyingType(property.PropertyType) : property.PropertyType);
dataTable.Columns.Add(property.Name, type);
}
DataRow dataRow;
foreach (T item in complexList)
{
dataRow = dataTable.NewRow(); // Create new DataRow with the same columns of DataTable
// novas linhas
foreach (PropertyInfo property in properties)
dataRow[property.Name] = property.GetValue(item) ?? DBNull.Value;
dataTable.Rows.Add(dataRow);
}
// nova linha
return dataTable;
}
If you want, you can do the same using Linq
protected virtual DataTable buildDataTableFromComplexTypeList<T>(string tableName, List<T> complexList)
{
DataTable tabela = new DataTable();
PropertyInfo[] propriedades = typeof(T).GetProperties();
tabela.Columns.AddRange(
propriedades.Select(p => new DataColumn(p.Name, (p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) ? Nullable.GetUnderlyingType(p.PropertyType) : p.PropertyType))).ToArray()
);
complexList.ForEach(
i => tabela.Rows.Add(
propriedades.Select(p => p.GetValue(i) ?? DBNull.Value).ToArray()
)
);
return tabela;
}
I adjusted the answer by placing @Jeferson Almeida on Nullable
because I remember that I have had problems with this in the past.
Sources:
LINQ: IENUMERABLE TO DATATABLE