C#教程之自己动手写映射第六节[封装列表]
一、动机
经过了前面几节的阐述,我们已经可以通过"动态生成SQL"与"反射机制"完成简单的对象与数据表的映射。如:Add(object obj)、Remove(object obj)等。好的,我们看如下代码:
1 public static List<Model.A> GetList(int PageSize, int CurrentPageIndex, out int TotalCount) 2 { 3 List<Model.A> listA = new List<Model.A>(); 4 DataSet ds = SqlCommon.GetList(conn, "ID", PageSize, PageSize * (CurrentPageIndex - 1), "A", "1=1", out TotalCount); 5 if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) 6 { 7 foreach (DataRow dr in ds.Tables[0].Rows) 8 { 9 Model.A employee = new Model.A(); 10 employee.ID = Convert.ToInt32(dr["ID"]); 11 employee.Name = dr["Name"].ToString(); 12 employee.Password = dr["Password"].ToString(); 13 employee.Department = dr["Department"].ToString(); 14 employee.Position = dr["Position"].ToString(); 15 listA.Add(employee); 16 } 17 } 18 return listA; 19 } 20 21 public static List<Model.B> GetList(int PageSize, int CurrentPageIndex, out int TotalCount) 22 { 23 List<Model.B> listB = new List<Model.B>(); 24 DataSet ds = SqlCommon.GetList(conn, "ID", PageSize, PageSize * (CurrentPageIndex - 1), "B", "1=1", out TotalCount); 25 if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) 26 { 27 foreach (DataRow dr in ds.Tables[0].Rows) 28 { 29 Model.B employee = new Model.B(); 30 employee.ID = Convert.ToInt32(dr["ID"]); 31 employee.Name = dr["Name"].ToString(); 32 employee.Password = dr["Password"].ToString(); 33 employee.Department = dr["Department"].ToString(); 34 employee.Position = dr["Position"].ToString(); 35 listB.Add(employee); 36 } 37 } 38 return listB; 39 }
我们在获取列表的时候总会对DataSet或DataReader里的数据进行转换,并放入到DTO中。
二、构想
我们是否可以把重复书写的代码进行封装并对外提供接口以简化我们的工作量呢...如下所示:
1 public static List<object> GetList(object classObject, string AssemblyName, string ConnString); 2 public static List<object> GetList(object classObject, string strWHERE, string AssemblyName, string ConnString); 3 public static List<object> GetList(object classObject, int intPageSize, int intCurrentCount, out int intTotalCount, string AssemblyName, string ConnString); 4 public static List<object> GetList(object classObject, int intPageSize, int intCurrentCount, string strWhere, out int intTotalCount, string AssemblyName, string ConnString);
这样我们再通过类型转换就可以使用List了.
三、实现
我们依然是依赖对象映射去转换DataSet,如下代码所示:
1 /// <summary> 2 /// 把DataSet 转换成为List 3 /// </summary> 4 /// <param name="ds"></param> 5 /// <param name="type"></param> 6 /// <param name="BaseFieldMapping"></param> 7 /// <returns></returns> 8 internal static List<object> ChangeDateSetToList(object classObject, Dictionary<string, string> FieldMapping, DataSet ds) 9 { 10 //获取传入的类型 11 Type type = classObject.GetType(); 12 //创建返回值 13 List<object> tempList = new List<object>(); 14 15 //检查DataSet的Table和Rows是否存在,至少取出一条数据 16 if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) 17 { 18 //获取属性名称及类型字典 19 PropertyInfo[] properInfo = type.GetProperties(); 20 Dictionary<string, Type> proDictionary = new Dictionary<string, Type>(); 21 foreach (PropertyInfo proper in properInfo) 22 { 23 proDictionary.Add(proper.Name, proper.PropertyType); 24 } 25 26 //遍历DataSet 27 int intRowCount = ds.Tables[0].Rows.Count; 28 for (int j = 0; j < intRowCount; j++) 29 { 30 //创建一个传入类型的新的实例 31 object typeTempObject = type.InvokeMember(null, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, null, null, null); 32 //属性赋值 33 foreach (string strKey in FieldMapping.Keys) 34 { 35 //根据数据类型取出值 36 object[] arrObject = Model.GetProType(classObject.GetType().GetProperty(strKey).PropertyType, ds.Tables[0].Rows[j][FieldMapping[strKey]].ToString()); 37 //属性赋值 38 type.InvokeMember(strKey, BindingFlags.SetProperty, null, typeTempObject, arrObject); 39 } 40 //将实体添加到 List 41 tempList.Add(typeTempObject); 42 //清空对象引用 43 typeTempObject = null; 44 } 45 } 46 return tempList; 47 }
四、版权