在web开发过程中,有时候为了数据传输的方便,比如:后台需要更新前端的ViewModel,此时我们定义一个与前端ViewModel结构一样的DTO对象,从数据层获取数据后,将数据封装成DTO然后序列化为json传回前端,由于我正在开发的项目中的Model是用DataSet来实现的,不是纯粹的面向对象(如果Model是对象的话可以用AutoMapper来实现转换),所以从数据层获取的都是DataSet或DataTable,这时需要将DataTable转换为DTO对象,DTO对象的属性与DataTable的列之间并不是一一对应的关系,为了转换方便,实现了一个简易的转换类,代码如下:
1 public class DtObjConverter 2 { 3 4 /// <summary> 5 /// 将DataTable转换成对象,对象的属性与列同名 6 /// </summary> 7 /// <typeparam name="T"></typeparam> 8 /// <param name="datatable"></param> 9 /// <returns></returns> 10 public List<T> ConvertTo<T>(DataTable datatable) where T : new() 11 { 12 List<T> Temp = new List<T>(); 13 try 14 { 15 List<string> columnsNames = new List<string>(); 16 foreach (DataColumn DataColumn in datatable.Columns) 17 columnsNames.Add(DataColumn.ColumnName); 18 Temp = datatable.AsEnumerable().ToList().ConvertAll<T>(row => getObject<T>(row, columnsNames)); 19 return Temp; 20 } 21 catch 22 { 23 return Temp; 24 } 25 26 } 27 28 /// <summary> 29 /// 将DataTable转换成对象,对象的属性会根据map参数进行转换 30 /// </summary> 31 /// <typeparam name="T"></typeparam> 32 /// <param name="datatable"></param> 33 /// <param name="map"></param> 34 /// <returns></returns> 35 public List<T> ConvertTo<T>(DataTable datatable, Hashtable map) where T : new() 36 { 37 List<T> Temp = new List<T>(); 38 try 39 { 40 List<string> columnsNames = new List<string>(); 41 foreach (DataColumn DataColumn in datatable.Columns) 42 columnsNames.Add(DataColumn.ColumnName); 43 Temp = datatable.AsEnumerable().ToList().ConvertAll<T>(row => getMapObject<T>(row, columnsNames, map)); 44 return Temp; 45 } 46 catch 47 { 48 return Temp; 49 } 50 51 } 52 53 /// <summary> 54 /// 根据DataTable生成对象,对象的属性与列同名 55 /// </summary> 56 /// <typeparam name="T"></typeparam> 57 /// <param name="row"></param> 58 /// <param name="columnsName"></param> 59 /// <returns></returns> 60 public T getObject<T>(DataRow row, List<string> columnsName) where T : new() 61 { 62 T obj = new T(); 63 try 64 { 65 string columnname = ""; 66 string value = ""; 67 PropertyInfo[] Properties; 68 Properties = typeof(T).GetProperties(); 69 foreach (PropertyInfo objProperty in Properties) 70 { 71 columnname = columnsName.Find(name => name.ToLower() == objProperty.Name.ToLower()); 72 if (!string.IsNullOrEmpty(columnname)) 73 { 74 value = row[columnname].ToString(); 75 if (!string.IsNullOrEmpty(value)) 76 { 77 if (Nullable.GetUnderlyingType(objProperty.PropertyType) != null) 78 { 79 value = row[columnname].ToString().Replace("$", "").Replace(",", ""); 80 objProperty.SetValue(obj, Convert.ChangeType(value, Type.GetType(Nullable.GetUnderlyingType(objProperty.PropertyType).ToString())), null); 81 } 82 else 83 { 84 value = row[columnname].ToString().Replace("%", ""); 85 objProperty.SetValue(obj, Convert.ChangeType(value, Type.GetType(objProperty.PropertyType.ToString())), null); 86 } 87 } 88 } 89 } 90 return obj; 91 } 92 catch 93 { 94 return obj; 95 } 96 } 97 98 /// <summary> 99 /// 根据DataTable生成对象,对象的属性会根据map参数进行转换 100 /// </summary> 101 /// <typeparam name="T"></typeparam> 102 /// <param name="row"></param> 103 /// <param name="columnsName"></param> 104 /// <returns></returns> 105 public T getMapObject<T>(DataRow row, List<string> columnsName, Hashtable map) where T : new() 106 { 107 T obj = new T(); 108 try 109 { 110 string columnname = ""; 111 string value = ""; 112 PropertyInfo[] Properties; 113 Properties = typeof(T).GetProperties(); 114 foreach (PropertyInfo objProperty in Properties) 115 { 116 string prpertyName = objProperty.Name; 117 columnname = columnsName.Find(name => name.ToLower() == map[prpertyName].ToString().ToLower()); 118 if (!string.IsNullOrEmpty(columnname)) 119 { 120 value = row[columnname].ToString(); 121 if (!string.IsNullOrEmpty(value)) 122 { 123 if (Nullable.GetUnderlyingType(objProperty.PropertyType) != null) 124 { 125 value = row[columnname].ToString().Replace("$", "").Replace(",", ""); 126 objProperty.SetValue(obj, Convert.ChangeType(value, Type.GetType(Nullable.GetUnderlyingType(objProperty.PropertyType).ToString())), null); 127 } 128 else 129 { 130 value = row[columnname].ToString().Replace("%", ""); 131 objProperty.SetValue(obj, Convert.ChangeType(value, Type.GetType(objProperty.PropertyType.ToString())), null); 132 } 133 } 134 } 135 } 136 return obj; 137 } 138 catch (Exception e) 139 { 140 string error = e.Message; 141 return obj; 142 } 143 } 144 145 public DataTable ToDataTable<T>(IEnumerable<T> collection) 146 { 147 DataTable newDataTable = new DataTable(); 148 Type impliedType = typeof(T); 149 PropertyInfo[] _propInfo = impliedType.GetProperties(); 150 foreach (PropertyInfo pi in _propInfo) 151 newDataTable.Columns.Add(pi.Name, pi.PropertyType); 152 153 foreach (T item in collection) 154 { 155 DataRow newDataRow = newDataTable.NewRow(); 156 newDataRow.BeginEdit(); 157 foreach (PropertyInfo pi in _propInfo) 158 newDataRow[pi.Name] = pi.GetValue(item, null); 159 newDataRow.EndEdit(); 160 newDataTable.Rows.Add(newDataRow); 161 } 162 return newDataTable; 163 } 164 165 }
用法:
DtObjConverterConvert convert = new DtObjConverterConvert (); //配置映射 Hashtable map = new Hashtable(); map.Add("Title", "name"); //key为对象属性名,value为表列名 /*----- 此处省略其他字段的添加 -----*/ List<YourDTOModel> dtoModelList = convert.ConvertTo<YourDTOModel>(dt, map);