C# 泛型对象和DataTable之间的相互转换
应用场景
实际开发场景下会经常出现DataTable和List对象需要相互转换的时候,通过方法提取避免重复造轮子
List转换成DataTable
基本思路:
向DataTable里面添加新的数据内容的话要确定两个部分,一是列名,而是当前列对应的值。通过获取传入对象的类型获取到当前对象的公共属性就可以得到列名,再对当前对象进行循环,就可以得到当前对象的该属性对应的值。
public static class DataTableHelper
{
public static DataTable ListToDataTable<TEntity>(List<TEntity> entities) where TEntity : class, new()
{
if (entities == null)
{
return null;
}
//获取模型类型
Type type = typeof(TEntity);
//获取该类型的公共属性
PropertyInfo[] properties = type.GetProperties();
DataTable dt = new DataTable(type.Name);
//根据属性名和属性类型向DataTable里面添加字段、字段类型
foreach (var item in properties)
{
dt.Columns.Add(new DataColumn(item.Name) { DataType = item.PropertyType });
}
foreach (var item in entities)
{
DataRow row = dt.NewRow();
foreach (var property in properties)
{
row[property.Name] = property.GetValue(item);
}
dt.Rows.Add(row);
}
return dt;
}
}
DataTable转List
基本思路
基本思路和上面的方法类似,获取当前准备转换对象的属性,然后循环DataTable对比是否存在当前属性名的列,存在则获取当前值。
public static IList<T> DataTableToList<T>(DataTable dt) where T : class, new()
{
if (dt.Rows.Count == 0)
{
return new List<T>();
}
IList<T> list = new List<T>();
Type type = typeof(T);
//获取当前类型公共属性
PropertyInfo[] properties = type.GetProperties();
foreach (DataRow dr in dt.Rows)
{
T t = new T();
foreach (var property in properties)
{
//对比列名确认数据是否存在
if (dt.Columns.Contains(property.Name))
{
//检查是否能写入
if (!property.CanWrite) continue;
var value = dr[property.Name];
if (value != null) { property.SetValue(t, value); }
}
}
}
return list;
}
DataTable转List
public static List<Dictionary<string,object>> DataToList(DataTable dt)
{
List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
foreach (DataRow dr in dt.Rows)
{
Dictionary<string, object> res = new Dictionary<string, object>();
foreach (DataColumn dc in dt.Columns)
{
res.Add(dc.ColumnName, dr[dc].ToString());
}
list.Add(res);
}
return list;
}