博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用反射将IDataReader读取到实体类中效率低下的解决办法
阅读量:6898 次
发布时间:2019-06-27

本文共 4525 字,大约阅读时间需要 15 分钟。

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

 
public static List
ToList
(IDataReader reader){ //实例化一个List<>泛型集合 List
DataList = new List
(); PropertyInfo[] properties = typeof(T).GetProperties().Union(typeof(T).BaseType.GetProperties()).ToArray(); while (reader.Read()) { T RowInstance = Activator.CreateInstance
();//动态创建数据实体对象 //通过反射取得对象所有的Property foreach (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
{ 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
CreateBuilder(IDataRecord dataRecord) { IDataReaderEntityBuilder
dynamicBuilder = new IDataReaderEntityBuilder
(); 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
ReaderToEntity
(IDataReader reader){ //实例化一个List<>泛型集合 List
list = new List
(); var builder = IDataReaderEntityBuilder
.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

你可能感兴趣的文章
Windows 7 无密码文件共享
查看>>
Sql server之sql注入篇
查看>>
CSS基本知识2-CSS选择
查看>>
Android中应用程序如何获得系统签名权限
查看>>
胖子哥的大数据之路(11)-我看Intel&&Cloudera的合作
查看>>
一个提供jsp免费空间的站点
查看>>
2014Esri全球用户大会之标准和互操作
查看>>
[歪谈]“走形式”的会议要不要滚粗
查看>>
wordpress表结构
查看>>
关于删除 hao123 主页设置的一点经验
查看>>
快速排序
查看>>
浅析Java虚拟机结构与机制[转]
查看>>
具体解释Android中AsyncTask的使用
查看>>
谷歌“信息安全公主”:我是一名好黑客
查看>>
Web Service学习笔记
查看>>
windows无法搜索新更新 80072ee2
查看>>
win7 32/64bit VS2010 OpenCV 2.4.9 环境配置
查看>>
tomcat配置虚拟主机
查看>>
【百度地图API】百度API卫星图使用方法和卫星图对比工具
查看>>
XCode中使用SVN 教程
查看>>