当前位置:
首页 > Python基础教程 >
-
ASP.net教程之大数据量下DataTable To List效率对比
反射将DataTable转为List方法
1 public static List<T> ToListByReflect<T>(this DataTable dt) where T : new() 2 { 3 List<T> ts = new List<T>(); 4 string tempName = string.Empty; 5 T t = new T(); 6 PropertyInfo[] propertys = t.GetType().GetProperties(); 7 foreach (DataRow dr in dt.Rows) 8 { 9 foreach (PropertyInfo pi in propertys) 10 { 11 tempName = pi.Name; 12 if (dt.Columns.Contains(tempName)) 13 { 14 object value = dr[tempName]; 15 if (value != DBNull.Value) 16 { 17 pi.SetValue(t, value, null); 18 } 19 } 20 } 21 ts.Add(t); 22 } 23 return ts; 24 }
动态生成代码将DataTable转为List方法
1 public static List<T> ToListByEmit<T>(this DataTable dt) where T : class, new() 2 { 3 List<T> list = new List<T>(); 4 if (dt == null || dt.Rows.Count == 0) 5 return list; 6 DataTableEntityBuilder<T> eblist = DataTableEntityBuilder<T>.CreateBuilder(dt.Rows[0]); 7 foreach (DataRow info in dt.Rows) 8 list.Add(eblist.Build(info)); 9 dt.Dispose(); 10 dt = null; 11 return list; 12 } 13 public class DataTableEntityBuilder<Entity> 14 { 15 private static readonly MethodInfo getValueMethod = typeof(DataRow).GetMethod("get_Item", new Type[] { typeof(int) }); 16 private static readonly MethodInfo isDBNullMethod = typeof(DataRow).GetMethod("IsNull", new Type[] { typeof(int) }); 17 private delegate Entity Load(DataRow dataRecord); 18 private Load handler; 19 private DataTableEntityBuilder() { } 20 public Entity Build(DataRow dataRecord) 21 { 22 return handler(dataRecord); 23 } 24 public static DataTableEntityBuilder<Entity> CreateBuilder(DataRow dataRecord) 25 { 26 DataTableEntityBuilder<Entity> dynamicBuilder = new DataTableEntityBuilder<Entity>(); 27 DynamicMethod method = new DynamicMethod("DynamicCreateEntity", typeof(Entity), new Type[] { typeof(DataRow) }, typeof(Entity), true); 28 ILGenerator generator = method.GetILGenerator(); 29 LocalBuilder result = generator.DeclareLocal(typeof(Entity)); 30 generator.Emit(OpCodes.Newobj, typeof(Entity).GetConstructor(Type.EmptyTypes)); 31 generator.Emit(OpCodes.Stloc, result); 32 for (int i = 0; i < dataRecord.ItemArray.Length; i++) 33 { 34 PropertyInfo propertyInfo = typeof(Entity).GetProperty(dataRecord.Table.Columns[i].ColumnName); 35 Label endIfLabel = generator.DefineLabel(); 36 if (propertyInfo != null && propertyInfo.GetSetMethod() != null) 37 { 38 generator.Emit(OpCodes.Ldarg_0); 39 generator.Emit(OpCodes.Ldc_I4, i); 40 generator.Emit(OpCodes.Callvirt, isDBNullMethod); 41 generator.Emit(OpCodes.Brtrue, endIfLabel); 42 generator.Emit(OpCodes.Ldloc, result); 43 generator.Emit(OpCodes.Ldarg_0); 44 generator.Emit(OpCodes.Ldc_I4, i); 45 generator.Emit(OpCodes.Callvirt, getValueMethod); 46 generator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); 47 generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod()); 48 generator.MarkLabel(endIfLabel); 49 } 50 } 51 generator.Emit(OpCodes.Ldloc, result); 52 generator.Emit(OpCodes.Ret); 53 dynamicBuilder.handler = (Load)method.CreateDelegate(typeof(Load)); 54 return dynamicBuilder; 55 } 56 }
然后写个控制台程序,对比一下两个方法的效率(测试类大概有40个属性)
电脑比较渣,使用Emit方法转换100w条数据大概需要7秒,而反射则需要37秒。还测试了当数据量比较小时,Reflect反而比较快。
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式