DbUtility-关于DataTable转成List的效率问题
DbUtility中的方法ExecuteDataTableAsync()得到的是一个DataTable,而我们常见的情况下,我们需要的不是DataTable,而是List或IList,所以现在需要考虑把DataTable转成List或IList,目前暂时有三种方案:
方案1:用动软生成代码:
1 public static List<Roles> GetRoleses(DataTable dt) 2 { 3 List<Roles> list = new List<Roles>(); 4 if (dt.Rows.Count > 0) 5 list.AddRange(from DataRow dataRow in dt.Rows select DataRowToModel(dataRow)); 6 return list; 7 } 8 9 /// <summary> 10 /// 得到一个对象实体 11 /// </summary> 12 private static Roles DataRowToModel(DataRow row) 13 { 14 Roles model = new Roles(); 15 if (row != null) 16 { 17 if (row["RoleID"] != null && row["RoleID"].ToString() != "") 18 { 19 model.RoleID = new Guid(row["RoleID"].ToString()); 20 } 21 if (row["RoleName"] != null) 22 { 23 model.RoleName = row["RoleName"].ToString(); 24 } 25 if (row["Description"] != null) 26 { 27 model.Description = row["Description"].ToString(); 28 } 29 if (row["TaskMask"] != null) 30 { 31 model.TaskMask = row["TaskMask"].ToString(); 32 } 33 if (row["RoleFlags"] != null && row["RoleFlags"].ToString() != "") 34 { 35 model.RoleFlags = int.Parse(row["RoleFlags"].ToString()); 36 } 37 } 38 return model; 39 }
循环遍历100W次,大约用时:14460毫秒。
方案2:用MVC.Net提供的反射方案:
1 public static IList<T> ConvertToModel<T>(this DataTable dt) where T : class, new() 2 { 3 // 定义集合 4 IList<T> ts = new List<T>(); 5 // 获得此模型的类型 6 Type type = typeof(T); 7 string tempName = ""; 8 foreach (DataRow dr in dt.Rows) 9 { 10 T t = new T(); 11 // 获得此模型的公共属性 12 PropertyInfo[] propertys = t.GetType().GetProperties(); 13 foreach (PropertyInfo pi in propertys) 14 { 15 tempName = pi.Name; 16 // 检查DataTable是否包含此列 17 if (dt.Columns.Contains(tempName)) 18 { 19 // 判断此属性是否有Setter 20 if (!pi.CanWrite) continue; 21 object value = dr[tempName]; 22 if (value != DBNull.Value) 23 pi.SetValue(t, value, null); 24 } 25 } 26 ts.Add(t); 27 } 28 return ts; 29 }
反射100W次,大约用时:20350毫秒。
方案3:用Melas提供的反射方案:
1 public static IList<T> ConvertTo<T>(DataTable table) 2 { 3 if (table == null) 4 { 5 return null; 6 } 7 List<DataRow> rows = new List<DataRow>(); 8 foreach (DataRow row in table.Rows) 9 { 10 rows.Add(row); 11 } 12 return ConvertTo<T>(rows); 13 } 14 public static IList<T> ConvertTo<T>(IList<DataRow> rows) 15 { 16 IList<T> list = null; 17 if (rows != null) 18 { 19 list = new List<T>(); 20 foreach (DataRow row in rows) 21 { 22 T item = CreateItem<T>(row); 23 list.Add(item); 24 } 25 } 26 return list; 27 } 28 public static T CreateItem<T>(DataRow row) 29 { 30 T obj = default(T); 31 if (row != null) 32 { 33 obj = Activator.CreateInstance<T>(); 34 foreach (DataColumn column in row.Table.Columns) 35 { 36 object value = row[column.ColumnName]; 37 PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName); 38 try 39 { 40 if (value != DBNull.Value && prop != null) 41 prop.SetValue(obj, value, null); 42 } 43 catch 44 { 45 // You can log something here 46 throw; 47 } 48 } 49 } 50 return obj; 51 }
反射100W次,大约用时:20258毫秒。
数据库结构:
|
原本想修改动软代码生成器的模板来生成改写过的DataRowToModel方法,想改成下面这样:
1 /// <summary> 2 /// 得到一个对象实体 3 /// </summary> 4 private static Roles DataRowToModel(DataRow row) 5 { 6 if (row != null) 7 { 8 Roles model = new Roles 9 { 10 RoleID = new Guid(row["RoleID"].ToString()), 11 RoleName = row["RoleName"].ToString(), 12 Description = row["Description"].ToString(), 13 TaskMask = row["TaskMask"].ToString(), 14 RoleFlags = int.Parse(row["RoleFlags"].ToString()) 15 }; 16 return model; 17 } 18 return null; 19 }
后来发现一个很悲剧的事,模板里不包含DataRowToModel方法,我看到了下面这个东西:
CPU:I7-3770
内存:4G*2
未完待续。。。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。