最开始使用反射一个类型的各个属性,对气进行赋值的代码如下:

public static List<T> ToList<T>(IDataReader reader)
{//实例化一个List<>泛型集合List<T> DataList = new List<T>();PropertyInfo[] properties = typeof(T).GetProperties().Union(typeof(T).BaseType.GetProperties()).ToArray();while (reader.Read()){T RowInstance = Activator.CreateInstance<T>();//动态创建数据实体对象//通过反射取得对象所有的Propertyforeach (PropertyInfo Property in properties){try{//取得当前数据库字段的顺序int Ordinal = reader.GetOrdinal(Property.Name);if (reader.GetValue(Ordinal) != DBNull.Value){//将DataReader读取出来的数据填充到对象实体的属性里Property.SetValue(RowInstance, Convert.ChangeType(reader.GetValue(Ordinal), Property.PropertyType), null);}}catch{break;}}DataList.Add(RowInstance);}return DataList;
}

以上代码封装一个320条记录、50个字段属性耗时13000豪秒,体验相当差。

后来改用以下这种方式后,性能大幅提升,同样是320条记录、50个字段仅用时17-26毫秒:

    public class IDataReaderEntityBuilder<Entity>{private static readonly MethodInfo getValueMethod = typeof(IDataRecord).GetMethod("get_Item", new Type[] { typeof(int) });private static readonly MethodInfo isDBNullMethod = typeof(IDataRecord).GetMethod("IsDBNull", new Type[] { typeof(int) });private delegate Entity Load(IDataRecord dataRecord);private Load handler;private IDataReaderEntityBuilder() { }public Entity Build(IDataRecord dataRecord) { return handler(dataRecord); }public static IDataReaderEntityBuilder<Entity> CreateBuilder(IDataRecord dataRecord){IDataReaderEntityBuilder<Entity> dynamicBuilder = new IDataReaderEntityBuilder<Entity>();DynamicMethod method = new DynamicMethod("IDataReaderDynamicCreateEntity", typeof(Entity), new Type[] { typeof(IDataRecord) }, typeof(Entity), true);ILGenerator generator = method.GetILGenerator();LocalBuilder result = generator.DeclareLocal(typeof(Entity));generator.Emit(OpCodes.Newobj, typeof(Entity).GetConstructor(Type.EmptyTypes));generator.Emit(OpCodes.Stloc, result);var properties = typeof(Entity).GetProperties();for (int i = 0; i < dataRecord.FieldCount; i++){PropertyInfo propertyInfo = typeof(Entity).GetProperty(properties.FirstOrDefault(x=>x.Name.ToUpper().Equals(dataRecord.GetName(i)))?.Name);Label endIfLabel = generator.DefineLabel();if (propertyInfo != null && propertyInfo.GetSetMethod() != null){generator.Emit(OpCodes.Ldarg_0);generator.Emit(OpCodes.Ldc_I4, i);generator.Emit(OpCodes.Callvirt, isDBNullMethod);generator.Emit(OpCodes.Brtrue, endIfLabel);generator.Emit(OpCodes.Ldloc, result);generator.Emit(OpCodes.Ldarg_0);generator.Emit(OpCodes.Ldc_I4, i);generator.Emit(OpCodes.Callvirt, getValueMethod);generator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod());generator.MarkLabel(endIfLabel);}}generator.Emit(OpCodes.Ldloc, result);generator.Emit(OpCodes.Ret);dynamicBuilder.handler = (Load)method.CreateDelegate(typeof(Load));return dynamicBuilder;}}

调用方式如下:

public static List<T> ReaderToEntity<T>(IDataReader reader)
{//实例化一个List<>泛型集合List<T> list = new List<T>();var builder = IDataReaderEntityBuilder<T>.CreateBuilder(reader);while (reader.Read()){var entity = builder.Build(reader);list.Add(entity);}return list;
}

反射慎用,奇慢无比。
相关参考:https://blog.csdn.net/livexy/article/details/6196193

http://www.cnblogs.com/liucfy/archive/2010/03/26/1696196.html

https://blog.csdn.net/lijing_zhaisky/article/details/7434622

https://www.cnblogs.com/livexy/archive/2010/09/01/1815330.html
---------------------
作者:bashigufen
来源:CSDN
原文:https://blog.csdn.net/lilong_herry/article/details/79993907

转载于:https://www.cnblogs.com/hnsongbiao/p/9931569.html

利用反射将IDataReader读取到实体类中效率低下的解决办法相关推荐

  1. 使用hibernate通过修改实体类文件更新数据库失效解决办法

    南波湾 配置文件中这个地方要设置 南波图 myeclipse/eclipse链接数据库正常 拉斯的玩 检查hibernate.cfg.xml文件中对应的实体类的mapping是否添加 我的问题就是最后 ...

  2. 关于java.util.LinkedHashMap cannot be cast to 实体类......问题的出现以及解决办法

    在使用RestTemplate调用服务的时候,因为服务提供者返回的是一个List集合,所以在使用消费者调用的时候,restTemplate.getForObject()期待返回的类型直接写成了List ...

  3. golang利用反射写入excel的简单工具类

    golang利用反射写入excel的简单工具类 工具类源码 使用方法 工具类源码 package excelimport ("errors""github.com/tea ...

  4. IDEA中根据数据库自动生成实体类,并自定义所生成的实体类中的注解 @Table @Id @...

    使用IDEA项目添加Hibernate扩展,生成实体类并配置实体类中的注解 一.使用Hibernate自动生成实体类 1.在项目上右键,选择Add Framework Support找到 Hibern ...

  5. 查询出的数据记录字段要与实体类中的属性名一致

    查询出的数据记录字段要与实体类中的属性名一致 转载于:https://www.cnblogs.com/1020182600HENG/p/6183031.html

  6. 【MyBatis】sql列名与实体类属性名不同的解决方式

    sql列名与Java实体类属性名不同的解决方式 例如: 数据库 CREATE TABLE orders(order_id INT PRIMARY KEY AUTO_INCREMENT,order_no ...

  7. java实体类中有枚举类型_当实体类中entity/DTO/VO等类中,有枚举值,应该怎么输出?...

    当实体类中entity/DTO/VO等类中,有枚举值,应该怎么输出? 问题: orderStatus 和 payStatus都是枚举类,并且枚举的个数达地10来个,我们不可能在模板页面(jsp/ftl ...

  8. Spring Boot接口返回的字段名和实体类中定义的字段名不一致

    问题描述:在使用@ResponseBody注解返回一个Controller接口数据时会遇到接口中返回的字段与实体中定义的字段不一致的情况,例如实体类中定义的字段名如下: @ApiModelProper ...

  9. EF架构~将数据库注释添加导入到模型实体类中

    回到目录 相关文章系列 第八回 EF架构~将数据库注释添加导入到模型实体类中 第二十一回  EF架构~为EF DbContext生成的实体添加注释(T4模板应用) 第二十二回  EF架构~为EF Db ...

  10. java实体类没有映射文件_MyBatis自动生成实体类、DAO和XML映射文件,并去掉实体类中的getter和setter方法...

    今天花了3个多小时搞定了这个事情,写个Blog记录一下,先看一下最终生成的实体类吧. packagecom.mybatis.pojo;importlombok.AllArgsConstructor;i ...

最新文章

  1. Android Studio(十二):打包多个发布渠道的apk文件
  2. 【职场攻略】是什么决定了我们的工资
  3. PWM波形的simulink仿真
  4. 面试官:你能告诉我一个请求过来,Spring MVC 是如何找到正确的 Controller 的?
  5. 解决linux下无线网卡被物理禁用问题
  6. php5.4配置gd库,php配置GD库
  7. 有关LinkedList常用方法的源码解析
  8. C#string与char互转
  9. 有道网页翻译chrome插件---我用过的最好的翻译插件
  10. 二分类模型评价指标-KS值
  11. sql 根据身份证号码计算年龄
  12. 【MATLAB】MATLAB 仿真模拟调制系统 — DSB 系统
  13. 终结HashMap面试?我是谁?我在哪
  14. 虚拟环境Vmware下改变Linux(CentOS7)IP地址
  15. 查看linux文件生成时间,【linux】如何查看文件的创建、修改时间
  16. 怎样关闭任务栏的Microsoft资讯
  17. 为何多语临床试验需要专业的翻译公司?
  18. 网络视频血战:弱者渔利
  19. iframe如何刷新的三种实现方案
  20. 电脑为什么刚开机时网速挺快,可过一段时间后就很慢了?重启电脑就解决了问题。

热门文章

  1. mysql_query 资源标识符_PHP mysql_query() 函数解析
  2. CS224N刷题——Assignment1.3_word2vec
  3. windows下phpstorm的高效使用
  4. springboot + redis(单机版)
  5. CKEditor 实例
  6. hdu 5437Alisha’s Party(优先队列)
  7. Markdown语法 (中文版)
  8. 基于cocos2d-x引擎的游戏框架设计
  9. HP大中华区总裁退休感言(孙振耀 )
  10. C#区分中英文统计字符串的长度