I am stuck with the following problem:
I normally use the function below to transfer custom data to DataTable but in this case the input data is a class composed of lists. I just need to write in DataTable the first element of each list per row. Could you help me to adjust this function in order to achieve this?
public List<int> xID { get; set; }
public List<string> xName { get; set; }
public List<string> xType { get; set; }
public List<string> xSource { get; set; }
public List<int> xmdID { get; set; }
public List<string> xMDName { get; set; }
public List<string> xUser { get; set; }
public static DataTable ListToDataTable<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, 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;
}
Based in Carra answer I tried the code below but it did not recognize pType type (The type or namespace name 'pType' could not be found (are you missing a using directive or an assembly reference?))
var v = properties[i].GetValue(entity);
Type pType = properties[i].PropertyType;
if (pType.IsGenericType && pType.GetGenericTypeDefinition() == typeof(Nullable<>))
pType = Nullable.GetUnderlyingType(pType);
if (pType.IsEnum)
pType = Enum.GetUnderlyingType(pType);
if (v.GetType().GetGenericTypeDefinition() == typeof(List<>))
{
values[i] = (v as List<pType>).First();
}
UPDATE
I guess it is not the best solution because it does not accept any List type but it is the best I could do:
public static DataTable ListToDataTable<T>(IEnumerable<T> list)
{
Type type = typeof(T);
var properties = type.GetProperties();
DataTable dataTable = new DataTable();
foreach (PropertyInfo info in properties)
{
Type propertyType = info.PropertyType;
if (propertyType.IsGenericType | propertyType.GetGenericTypeDefinition() == typeof(Nullable<>) | propertyType.IsEnum)
propertyType = propertyType.GetGenericArguments()[0];
dataTable.Columns.Add(new DataColumn(info.Name, propertyType));
}
foreach (T entity in list)
{
object[] values = new object[properties.Length];
for (int i = 0; i < properties.Length; i++)
{
var v = properties[i].GetValue(entity);
Type pType = v.GetType().GetGenericArguments().FirstOrDefault();
if (v.GetType().GetGenericTypeDefinition() == typeof(List<>))
{
if(pType == typeof(int))
values[i] = (v as List<int>).First();
else if(pType == typeof(string))
values[i] = (v as List<string>).First();
}
else
{
values[i] = v;
}
}
dataTable.Rows.Add(values);
}
return dataTable;
}
You need something like this:
foreach (PropertyInfo info in properties)
{
if(info.PropertyType == typeof(IEnumerable))
{
dataTable.Columns.Add(new DataColumn(info.Name, info.Cast<object>().First().GetType());
}
else
{
dataTable.Columns.Add(new DataColumn(info.Name, info.PropertyType));
}
}
foreach (T entity in list)
{
object[] values = new object[properties.Length];
for (int i = 0; i < properties.Length; i++)
{
var v = properties[i].GetValue(entity);
if(v is IEnumerable)
{
values[i] = (v.Cast<object>().First()).First();
}
else
{
values[i] = v;
}
}
dataTable.Rows.Add(values);
}
This works for me. I got it here and modified it a little bit.
public static DataTable ToDataTable<T>(this System.Collections.Generic.List<T> collection, string _sTableName) {
var table = new DataTable(_sTableName);
var type = typeof(T);
var properties = type.GetProperties();
//Create the columns in the DataTable
foreach (var property in properties) {
if (property.PropertyType == typeof(int?)) {
table.Columns.Add(property.Name, typeof(int));
} else if (property.PropertyType == typeof(decimal?)) {
table.Columns.Add(property.Name, typeof(decimal));
} else if (property.PropertyType == typeof(double?)) {
table.Columns.Add(property.Name, typeof(double));
} else if (property.PropertyType == typeof(DateTime?)) {
table.Columns.Add(property.Name, typeof(DateTime));
} else if (property.PropertyType == typeof(Guid?)) {
table.Columns.Add(property.Name, typeof(Guid));
} else if (property.PropertyType == typeof(bool?)) {
table.Columns.Add(property.Name, typeof(bool));
} else {
table.Columns.Add(property.Name, property.PropertyType);
}
}
//Populate the table
foreach (var item in collection) {
var row = table.NewRow();
row.BeginEdit();
foreach (var property in properties) {
row[property.Name] = property.GetValue(item, null) ?? DBNull.Value;
}
row.EndEdit();
table.Rows.Add(row);
}
return table;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.