using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace Xmh.DBUnit { /// <summary> /// 将DataTable转换为List,将List转换为DataTable的实现类 /// </summary> public static class DataTableHelper { public static DataTable ConvertTo<T>(IList<T> list) { DataTable table = CreateTable<T>(); Type entityType = typeof(T); PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType); foreach (T item in list) { DataRow row = table.NewRow(); foreach (PropertyDescriptor prop in properties) row[prop.Name] = prop.GetValue(item); table.Rows.Add(row); } return table; } public static IList<T> ConvertTo<T>(IList<DataRow> rows) { IList<T> list = null; if (rows != null) { list = new List<T>(); foreach (DataRow row in rows) { T item = CreateItem<T>(row); list.Add(item); } } return list; } public static IList<T> ConvertTo<T>(DataTable table) { if (table == null) return null; List<DataRow> rows = new List<DataRow>(); foreach (DataRow row in table.Rows) rows.Add(row); return ConvertTo<T>(rows); } //Convert DataRow into T Object public static T CreateItem<T>(DataRow row) { string columnName; T obj = default(T); if (row != null) { obj = Activator.CreateInstance<T>(); foreach (DataColumn column in row.Table.Columns) { columnName = column.ColumnName; //Get property with same columnName PropertyInfo prop = obj.GetType().GetProperty(columnName); try { Type type = prop.PropertyType; //判断type类型是否为泛型,因为nullable是泛型类, if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))//判断convertsionType是否为nullable泛型类 { //如果type为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换 System.ComponentModel.NullableConverter nullableConverter = new System.ComponentModel.NullableConverter(type); //将type转换为nullable对的基础基元类型 type = nullableConverter.UnderlyingType; } //Get value for the column object value = (row[columnName].GetType() == typeof(DBNull)) ? null : row[columnName]; //Set property value if (prop.CanWrite) //判断其是否可写 prop.SetValue(obj, (value == null ? null : Convert.ChangeType(value, type)), null); } catch { throw; //Catch whatever here } } } return obj; } public static DataTable CreateTable<T>() { Type entityType = typeof(T); DataTable table = new DataTable(entityType.Name); PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType); foreach (PropertyDescriptor prop in properties) table.Columns.Add(prop.Name, prop.PropertyType); return table; } public static List<T> ToList<T>(this DataTable dt) where T : class, new() { Type t = typeof(T); PropertyInfo[] propertys = t.GetProperties(); List<T> lst = new List<T>(); string typeName = string.Empty; foreach (DataRow dr in dt.Rows) { T entity = new T(); foreach (PropertyInfo pi in propertys) { typeName = pi.Name; if (dt.Columns.Contains(typeName)) { if (!pi.CanWrite) continue; object value = dr[typeName]; if (value == DBNull.Value) continue; if (pi.PropertyType == typeof(string)) { pi.SetValue(entity, value.ToString(), null); } else if (pi.PropertyType == typeof(int) || pi.PropertyType == typeof(int?)) { pi.SetValue(entity, int.Parse(value.ToString()), null); } else if (pi.PropertyType == typeof(DateTime?) || pi.PropertyType == typeof(DateTime)) { pi.SetValue(entity, DateTime.Parse(value.ToString()), null); } else if (pi.PropertyType == typeof(float)) { pi.SetValue(entity, float.Parse(value.ToString()), null); } else if (pi.PropertyType == typeof(double)) { pi.SetValue(entity, double.Parse(value.ToString()), null); } else { pi.SetValue(entity, value, null); } } } lst.Add(entity); } return lst; } } }