1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using System.Data; 5 using System.Linq; 6 using System.Reflection; 7 using System.Text; 8 9 namespace TransformDTToModel 10 { 11 public class TransformUtil 12 { 13 ///14 /// 将DB中改动的内容同步到泛型集合中 15 /// 16 ///类型 17 /// dt源 18 /// 目标Model集合 19 ///20 public static bool ConvertDataTableToModel (DataTable source, List destinationArray) 21 where T : class 22 { 23 if (source == null || destinationArray == null || source.PrimaryKey == null || source.PrimaryKey.Count() <= 0) 24 return false; 25 26 DataTable dtChange = source.GetChanges(); 27 if (dtChange == null) 28 return false; 29 30 List keys = new List (); 31 foreach (var item in source.PrimaryKey) 32 { 33 keys.Add(item.ColumnName); 34 } 35 36 return ConvertDataTableToModel(source, destinationArray, keys); 37 } 38 39 /// 40 /// 同步table里改动的数据到泛型集合里去(新增,修改,删除) 41 /// 42 ///类型 43 /// dt源 44 /// 目标Model集合 45 /// 主键集合 46 ///47 public static bool ConvertDataTableToModel (DataTable source, List destinationArray, List keyColumnArray) 48 where T : class 49 { 50 if (source == null || destinationArray == null || source.Rows.Count == 0 || keyColumnArray == null || keyColumnArray.Count == 0) 51 return false; 52 53 Type modeType = destinationArray.GetType().GetGenericArguments()[0];//模型类型 54 PropertyInfo[] ppInfoArray = modeType.GetProperties();//公共属性集合 55 List listPPInfo = ppInfoArray.ToList();//方便查询 56 //关键列 57 List keyPIArray = listPPInfo.FindAll(x => keyColumnArray.Contains(x.Name)); 58 59 List listToDelete = new List (); 60 //新增的数据 61 DataRow[] drAddArray = source.Select("", "", DataViewRowState.Added); 62 63 object objItem = modeType.Assembly.CreateInstance(modeType.FullName); 64 foreach (DataRow dr in drAddArray) 65 { 66 destinationArray.Add((T)objItem); 67 foreach (System.Reflection.PropertyInfo pi in listPPInfo) 68 { 69 pi.SetValue(destinationArray[destinationArray.Count - 1], dr[pi.Name], null); 70 } 71 } 72 //修改和删除的数据 73 DataView dvForOP = new DataView(source); 74 dvForOP.RowStateFilter = DataViewRowState.Deleted | DataViewRowState.ModifiedCurrent; 75 76 foreach (DataRowView drv in dvForOP) 77 { 78 for (int i = 0; i < destinationArray.Count; i++) 79 { 80 bool blIsTheRow = true; 81 //找出关键列对应的行 82 foreach (System.Reflection.PropertyInfo pInfo in keyPIArray) 83 { 84 object okey = pInfo.GetValue(destinationArray[i], null); 85 if (okey == null) 86 continue; 87 if (drv[pInfo.Name].ToString() != okey.ToString()) 88 { 89 blIsTheRow = false; 90 break; 91 } 92 } 93 if (!blIsTheRow)//非本行 94 continue; 95 //根据行状态同步赋值 96 switch (drv.Row.RowState) 97 { 98 case DataRowState.Modified: 99 {100 foreach (System.Reflection.PropertyInfo pi in listPPInfo)101 {102 if (keyPIArray.Contains(pi))//主键列不更新103 continue;104 pi.SetValue(destinationArray[i], drv[pi.Name], null);105 }106 } break;107 case DataRowState.Deleted:108 {109 listToDelete.Add(destinationArray[i]);110 } break;111 }112 }113 }114 115 for (int i = 0; i < listToDelete.Count; i++)116 {117 destinationArray.Remove(listToDelete[i]);118 }119 120 return true;121 }122 123 /// 124 /// 将视图转换成泛型集合125 /// 126 ///类型 127 /// 视图128 /// 泛型实例129 ///130 public static List ConvertDataViewToModel (DataView dataView, T model)131 where T:class132 {133 List listReturn = new List ();134 Type modelType = model.GetType();135 DataTable dt = dataView.Table;136 //获取model所有类型137 PropertyInfo[] modelProperties = modelType.GetProperties();138 139 //遍历所有行,逐行添加对象140 for (int i = 0; i < dt.Rows.Count; i++)141 {142 object obj = modelType.Assembly.CreateInstance(modelType.FullName);143 listReturn.Add((T)obj);144 //遍历model所有属性145 foreach (PropertyInfo pi in modelProperties)146 {147 //遍历所有列148 foreach (DataColumn col in dt.Columns)149 {150 //如果列数据类型与model的数据类型相同、名称相同151 if (col.DataType == pi.PropertyType152 && col.ColumnName == pi.Name)153 {154 pi.SetValue(obj, dt.Rows[i][col.ColumnName], null);155 }156 }157 }158 }159 160 return listReturn;161 }162 163 /// 164 /// 将泛型集合类转换成DataTable165 /// 166 ///集合项类型 167 /// 集合168 /// 需要返回的列的列名,如需返回所有列,此参数传入null值169 ///数据集(表) 170 public static DataTable ConvertModelToDataTable(IList sourceArray, params string[] propertyNameArray)171 where T:class172 {173 List propertyNameList = new List ();174 if (propertyNameArray != null)175 propertyNameList.AddRange(propertyNameArray);176 177 DataTable result = new DataTable();178 //获取结构179 Type[] typeArr = sourceArray.GetType().GetGenericArguments();180 if (typeArr.Length == 0)181 return result;182 183 PropertyInfo[] propertys = typeArr[0].GetProperties();184 foreach (PropertyInfo pi in propertys)185 {186 if (propertyNameList.Count == 0)187 {188 result.Columns.Add(pi.Name, pi.PropertyType);189 }190 else191 {192 if (propertyNameList.Contains(pi.Name))193 result.Columns.Add(pi.Name, pi.PropertyType);194 }195 }196 for (int i = 0; i < sourceArray.Count; i++)197 {198 ArrayList tempList = new ArrayList();199 foreach (PropertyInfo pi in propertys)200 {201 if (propertyNameList.Count == 0)202 {203 object obj = pi.GetValue(sourceArray[i], null);204 tempList.Add(obj);205 }206 else207 {208 if (propertyNameList.Contains(pi.Name))209 {210 object obj = pi.GetValue(sourceArray[i], null);211 tempList.Add(obj);212 }213 }214 }215 object[] array = tempList.ToArray();216 result.LoadDataRow(array, true);217 }218 219 return result;220 }221 222 }223 }
public class People { public string Id { get; set; } public string Name { get; set; } public string Address { get; set; } }
单元测试
[TestClass] public class UnitTestForTransformDTAndModel { [TestMethod] public void TestConvertDataTableToModel() { DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(string)); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("Address", typeof(string)); dt.PrimaryKey = new DataColumn[] { dt.Columns[0] }; dt.Rows.Add("0001", "张三", "武汉市"); dt.Rows.Add("0002", "李四", "北京市"); dt.AcceptChanges(); dt.Rows.Add("0003", "王五", "深圳市"); ListallPeople = new List (); TransformUtil.ConvertDataTableToModel (dt, allPeople); //断言是不是只有一个数据,平且是只是修改状态的王五这个人 Assert.AreEqual(allPeople.Count, 1); Assert.AreEqual(allPeople[0].Name, "王五"); } [TestMethod] public void TestConvertModelToDataTable() { List allPeople = new List () { new People(){ Id="0001", Name="张三", Address ="武汉市"}, new People(){ Id="0002", Name="李四", Address ="北京市"}, new People(){ Id="0003", Name="王五", Address ="深圳市"} }; DataTable dt = TransformUtil.ConvertModelToDataTable (allPeople, null); //断言是不是有3行数据,数据的列有3列,第1列是不是Id,第一行第二列是不是张三 Assert.AreEqual(dt.Rows.Count, 3); Assert.AreEqual(dt.Columns.Count, 3); Assert.AreEqual(dt.Columns[0].ColumnName, "Id"); Assert.AreEqual(dt.Rows[0][1], "张三"); } }