使用Emit把Datatable转换为对象集合(List<T>)
Emit生成动态方法部分摘自网上,但是经过修改,加入了对委托的缓存以及类结构的调整,使之调用更简洁方便。大致的思路是:要实现转换datatable到某个指定对象的集合,本质是实现转换一个datarow到一个指定的对象。利用Emit动态构造该方法并缓存起来,调用时从缓存查找出来并调用,就这么简单。上代码:
- /// <summary>
- /// 把datatable转换为对象集合列表List<T>
- /// </summary>
- public class DataTableConvert
- {
- //把DataRow转换为对象的委托声明
- private delegate T Load<T>(DataRow dataRecord);
- //用于构造Emit的DataRow中获取字段的方法信息
- private static readonly MethodInfo getValueMethod = typeof(DataRow).GetMethod("get_Item", new Type[] { typeof(int) });
- //用于构造Emit的DataRow中判断是否为空行的方法信息
- private static readonly MethodInfo isDBNullMethod = typeof(DataRow).GetMethod("IsNull", new Type[] { typeof(int) });
- //使用字典存储实体的类型以及与之对应的Emit生成的转换方法
- private static Dictionary<Type, Delegate> rowMapMethods = new Dictionary<Type, Delegate>();
- public static List<T> ToList<T>(DataTable dt)
- {
- List<T> list = new List<T>();
- if (dt == null)
- return list;
- //声明 委托Load<T>的一个实例rowMap
- Load<T> rowMap = null;
- //从rowMapMethods查找当前T类对应的转换方法,没有则使用Emit构造一个。
- if (!rowMapMethods.ContainsKey(typeof(T)))
- {
- DynamicMethod method = new DynamicMethod("DynamicCreateEntity_" + typeof(T).Name, typeof(T), new Type[] { typeof(DataRow) }, typeof(T), true);
- ILGenerator generator = method.GetILGenerator();
- LocalBuilder result = generator.DeclareLocal(typeof(T));
- generator.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes));
- generator.Emit(OpCodes.Stloc, result);
- for (int index = ; index < dt.Columns.Count; index++)
- {
- PropertyInfo propertyInfo = typeof(T).GetProperty(dt.Columns[index].ColumnName,StringComparison.CurrentCultureIgnoreCase);
- Label endIfLabel = generator.DefineLabel();
- if (propertyInfo != null && propertyInfo.GetSetMethod() != null)
- {
- generator.Emit(OpCodes.Ldarg_0);
- generator.Emit(OpCodes.Ldc_I4, index);
- 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, index);
- 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);
- //构造完成以后传给rowMap
- rowMap = (Load<T>)method.CreateDelegate(typeof(Load<T>));
- }
- else
- {
- rowMap = (Load<T>)rowMapMethods[typeof(T)];
- }
- //遍历Datatable的rows集合,调用rowMap把DataRow转换为对象(T)
- foreach (DataRow info in dt.Rows)
- list.Add(rowMap(info));
- return list;
- }
- }
使用Emit把Datatable转换为对象集合(List<T>)的更多相关文章
- 再谈使用Emit把Datatable转换为对象集合(List<T>)
一.前因和存在的问题 前面我写了一篇<使用Emit把Datatable转换为对象集合(List<T>)>的博文,其实起源于我自己编写的一个orm工具(见前面几篇博文有介绍),里 ...
- 【转】给DataTable和DataRow扩展方法,直接转换为对象集合或对象
/// <summary> /// 类 说 明:给DataTable和DataRow扩展方法,直接转换为对象集合或对象 /// 补充说明:此扩展类可以极大的简化操作,但是性能低下,大数据以 ...
- 对象列表转换为DataTable或DataTable转换为对象列表.
/**********************************************************************************/ // 说明: 数据转换工具. ...
- Java技巧——将前端的对象数组通过Json字符串传到后端并转换为对象集合
Java技巧——将前端的对象数组通过Json字符串传到后端并转换为对象集合 摘要:本文主要记录了如何将将前端的对象数组通过Json字符串传到后端,并在后端将Json字符串转换为对象集合. 前端代码 前 ...
- DataTable转换为实体集合
using System; using System.Collections; using System.Collections.Generic; using System.Data; using S ...
- [工具类]DataTable与泛型集合List互转
写在前面 工作中经常遇到datatable与list,对于datatable而言操作起来不太方便.所以有的时候还是非常希望通过泛型集合来进行操作的.所以这里就封装了一个扩展类.也方便使用. 类 方法中 ...
- C#中对象,字符串,dataTable、DataReader、DataSet,对象集合转换成Json字符串方法。
C#中对象,字符串,dataTable.DataReader.DataSet,对象集合转换成Json字符串方法. public class ConvertJson { #region 私有方法 /// ...
- [Json] C#ConvertJson|List转成Json|对象|集合|DataSet|DataTable|DataReader转成Json (转载)
点击下载 ConvertJson.rar 本类实现了 C#ConvertJson|List转成Json|对象|集合|DataSet|DataTable|DataReader转成Json|等功能大家先预 ...
- 将DataTable转换为List<T>对象遇到问题:类型“System.Int64”的对象无法转换为类型“System.Int32”。
可以利用反射将DataTable转换为List<T>对象:原始链接http://www.jb51.net/article/67386.htm 但是该方法在DataTable里某个字段类型是 ...
随机推荐
- 我的Python学习之路 Python的输入输出与基本数据类型
*** python中的变量不需要事先声明再使用,而可以直接来一个变量名,后面一个赋值,接着一个数据值,如 hw = "hello python",相当于Python能智能的根据你 ...
- webpack 打包一个简单react组件
安装Webpack,并加载一个简单的React组件 全局的npm模块安装: npm install -g webpack 安装jsx-loader npm install --save-dev jsx ...
- IOS UIAppLocation 单例模式
UIApplocation * app=[UIApplocation shareapplocation]; UIAppLocation 只能被初始化一次. 一个程序中只能被创建一次,称为单例模式. 单 ...
- <转>Unity3D研究院之C#使用Socket与HTTP连接服务器传输数据包
最近项目中需要使用HTTP与Socket,把自己这段时间学习的资料整理一下.有关Socket与HTTP的基础知识MOMO就不赘述拉,不懂得朋友自己谷歌吧.我们项目的需求是在登录的时候使用HTTP请求, ...
- 关于在header里增加参数的方式
在使用一个API的时候,文档里写的返回值类型是json,可是试了下返回的明明是xml,还小小的鄙视了一把. 可是解析xml,好麻烦的.最好是json可以直接decode . 意外看到文档下面有一句 J ...
- WPF-系统托盘
WPFSystemTray.cs public class WPFSystemTray { /// <summary> /// 设置系统托盘 /// </summary> // ...
- Java_位运算(移位、位与、或、异或、非)
public class Test { public static void main(String[] args) { // 1.左移( << ) // 0000 0000 0000 0 ...
- spring里的controller之间的跳转
未测试: this.getServletContext().getRequestDispatcher("/rentHouse.htm?method=display").forwar ...
- 基于thinkphp的省略图便捷函数
/** * 生成缩略图 * @param string $image 原图路径 例:thumb_5242d9082fcdc.jpg * @param string $type 图像格式 * @para ...
- java-sql注入攻击
注射式攻击的原理 SQL注射能使攻击者绕过认证机制,完全控制远程服务器上的数据库.SQL是结构化查询语言的简称,它是访问数据库的事实标准.目前,大多数Web应用都使用SQL数据库来存放应用程序的数据. ...