首页 > 代码库 > DbUtility-关于DataTable转成List的效率问题

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 =http://www.mamicode.com/ 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 =http://www.mamicode.com/ 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毫秒。

 

数据库结构:

表名:Roles
 
序号 列名 数据类型 长度 小数位 标识 主键 允许空 默认值 说明
1 RoleID uniqueidentifier 16 0        
2 RoleName nvarchar 260 0        
3 Description nvarchar 512 0        
4 TaskMask nvarchar 32 0        
5 RoleFlags tinyint 1 0        

 

原本想修改动软代码生成器的模板来生成改写过的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

 

未完待续。。。