Emit生成动态方法部分摘自网上,但是经过修改,加入了对委托的缓存以及类结构的调整,使之调用更简洁方便。大致的思路是:要实现转换datatable到某个指定对象的集合,本质是实现转换一个datarow到一个指定的对象。利用Emit动态构造该方法并缓存起来,调用时从缓存查找出来并调用,就这么简单。上代码:

  1. /// <summary>
  2. /// 把datatable转换为对象集合列表List<T>
  3. /// </summary>
  4. public class DataTableConvert
  5. {
  6. //把DataRow转换为对象的委托声明
  7. private delegate T Load<T>(DataRow dataRecord);
  8.  
  9. //用于构造Emit的DataRow中获取字段的方法信息
  10. private static readonly MethodInfo getValueMethod = typeof(DataRow).GetMethod("get_Item", new Type[] { typeof(int) });
  11.  
  12. //用于构造Emit的DataRow中判断是否为空行的方法信息
  13. private static readonly MethodInfo isDBNullMethod = typeof(DataRow).GetMethod("IsNull", new Type[] { typeof(int) });
  14.  
  15. //使用字典存储实体的类型以及与之对应的Emit生成的转换方法
  16. private static Dictionary<Type, Delegate> rowMapMethods = new Dictionary<Type, Delegate>();
  17.  
  18. public static List<T> ToList<T>(DataTable dt)
  19. {
  20. List<T> list = new List<T>();
  21. if (dt == null)
  22. return list;
  23.  
  24. //声明 委托Load<T>的一个实例rowMap
  25. Load<T> rowMap = null;
  26.  
  27. //从rowMapMethods查找当前T类对应的转换方法,没有则使用Emit构造一个。
  28. if (!rowMapMethods.ContainsKey(typeof(T)))
  29. {
  30. DynamicMethod method = new DynamicMethod("DynamicCreateEntity_" + typeof(T).Name, typeof(T), new Type[] { typeof(DataRow) }, typeof(T), true);
  31. ILGenerator generator = method.GetILGenerator();
  32. LocalBuilder result = generator.DeclareLocal(typeof(T));
  33. generator.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes));
  34. generator.Emit(OpCodes.Stloc, result);
  35.  
  36. for (int index = ; index < dt.Columns.Count; index++)
  37. {
  38. PropertyInfo propertyInfo = typeof(T).GetProperty(dt.Columns[index].ColumnName,StringComparison.CurrentCultureIgnoreCase);
  39. Label endIfLabel = generator.DefineLabel();
  40. if (propertyInfo != null && propertyInfo.GetSetMethod() != null)
  41. {
  42. generator.Emit(OpCodes.Ldarg_0);
  43. generator.Emit(OpCodes.Ldc_I4, index);
  44. generator.Emit(OpCodes.Callvirt, isDBNullMethod);
  45. generator.Emit(OpCodes.Brtrue, endIfLabel);
  46. generator.Emit(OpCodes.Ldloc, result);
  47. generator.Emit(OpCodes.Ldarg_0);
  48. generator.Emit(OpCodes.Ldc_I4, index);
  49. generator.Emit(OpCodes.Callvirt, getValueMethod);
  50. generator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
  51. generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod());
  52. generator.MarkLabel(endIfLabel);
  53. }
  54. }
  55. generator.Emit(OpCodes.Ldloc, result);
  56. generator.Emit(OpCodes.Ret);
  57.  
  58. //构造完成以后传给rowMap
  59. rowMap = (Load<T>)method.CreateDelegate(typeof(Load<T>));
  60. }
  61. else
  62. {
  63. rowMap = (Load<T>)rowMapMethods[typeof(T)];
  64. }
  65.  
  66. //遍历Datatable的rows集合,调用rowMap把DataRow转换为对象(T)
  67. foreach (DataRow info in dt.Rows)
  68. list.Add(rowMap(info));
  69. return list;
  70.  
  71. }
  72. }

使用Emit把Datatable转换为对象集合(List<T>)的更多相关文章

  1. 再谈使用Emit把Datatable转换为对象集合(List<T>)

    一.前因和存在的问题 前面我写了一篇<使用Emit把Datatable转换为对象集合(List<T>)>的博文,其实起源于我自己编写的一个orm工具(见前面几篇博文有介绍),里 ...

  2. 【转】给DataTable和DataRow扩展方法,直接转换为对象集合或对象

    /// <summary> /// 类 说 明:给DataTable和DataRow扩展方法,直接转换为对象集合或对象 /// 补充说明:此扩展类可以极大的简化操作,但是性能低下,大数据以 ...

  3. 对象列表转换为DataTable或DataTable转换为对象列表.

    /**********************************************************************************/ // 说明: 数据转换工具. ...

  4. Java技巧——将前端的对象数组通过Json字符串传到后端并转换为对象集合

    Java技巧——将前端的对象数组通过Json字符串传到后端并转换为对象集合 摘要:本文主要记录了如何将将前端的对象数组通过Json字符串传到后端,并在后端将Json字符串转换为对象集合. 前端代码 前 ...

  5. DataTable转换为实体集合

    using System; using System.Collections; using System.Collections.Generic; using System.Data; using S ...

  6. [工具类]DataTable与泛型集合List互转

    写在前面 工作中经常遇到datatable与list,对于datatable而言操作起来不太方便.所以有的时候还是非常希望通过泛型集合来进行操作的.所以这里就封装了一个扩展类.也方便使用. 类 方法中 ...

  7. C#中对象,字符串,dataTable、DataReader、DataSet,对象集合转换成Json字符串方法。

    C#中对象,字符串,dataTable.DataReader.DataSet,对象集合转换成Json字符串方法. public class ConvertJson { #region 私有方法 /// ...

  8. [Json] C#ConvertJson|List转成Json|对象|集合|DataSet|DataTable|DataReader转成Json (转载)

    点击下载 ConvertJson.rar 本类实现了 C#ConvertJson|List转成Json|对象|集合|DataSet|DataTable|DataReader转成Json|等功能大家先预 ...

  9. 将DataTable转换为List<T>对象遇到问题:类型“System.Int64”的对象无法转换为类型“System.Int32”。

    可以利用反射将DataTable转换为List<T>对象:原始链接http://www.jb51.net/article/67386.htm 但是该方法在DataTable里某个字段类型是 ...

随机推荐

  1. 我的Python学习之路 Python的输入输出与基本数据类型

    *** python中的变量不需要事先声明再使用,而可以直接来一个变量名,后面一个赋值,接着一个数据值,如 hw = "hello python",相当于Python能智能的根据你 ...

  2. webpack 打包一个简单react组件

    安装Webpack,并加载一个简单的React组件 全局的npm模块安装: npm install -g webpack 安装jsx-loader npm install --save-dev jsx ...

  3. IOS UIAppLocation 单例模式

    UIApplocation * app=[UIApplocation shareapplocation]; UIAppLocation 只能被初始化一次. 一个程序中只能被创建一次,称为单例模式. 单 ...

  4. <转>Unity3D研究院之C#使用Socket与HTTP连接服务器传输数据包

    最近项目中需要使用HTTP与Socket,把自己这段时间学习的资料整理一下.有关Socket与HTTP的基础知识MOMO就不赘述拉,不懂得朋友自己谷歌吧.我们项目的需求是在登录的时候使用HTTP请求, ...

  5. 关于在header里增加参数的方式

    在使用一个API的时候,文档里写的返回值类型是json,可是试了下返回的明明是xml,还小小的鄙视了一把. 可是解析xml,好麻烦的.最好是json可以直接decode . 意外看到文档下面有一句 J ...

  6. WPF-系统托盘

    WPFSystemTray.cs public class WPFSystemTray { /// <summary> /// 设置系统托盘 /// </summary> // ...

  7. Java_位运算(移位、位与、或、异或、非)

    public class Test { public static void main(String[] args) { // 1.左移( << ) // 0000 0000 0000 0 ...

  8. spring里的controller之间的跳转

    未测试: this.getServletContext().getRequestDispatcher("/rentHouse.htm?method=display").forwar ...

  9. 基于thinkphp的省略图便捷函数

    /** * 生成缩略图 * @param string $image 原图路径 例:thumb_5242d9082fcdc.jpg * @param string $type 图像格式 * @para ...

  10. java-sql注入攻击

    注射式攻击的原理 SQL注射能使攻击者绕过认证机制,完全控制远程服务器上的数据库.SQL是结构化查询语言的简称,它是访问数据库的事实标准.目前,大多数Web应用都使用SQL数据库来存放应用程序的数据. ...