使用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遍历一个网段的ip地址
def ip2num(ip):#ip to int num lp = [int(x) for x in ip.split('.')] return lp[0] << 24 | lp[1] ...
- supervisor-1:基础篇
别人博客转载,做个记录 原文链接:http://lixcto.blog.51cto.com/4834175/1539136 有阵子没写博客了,这段时间一直在研究python django框架和前端相关 ...
- H5 video的使用
html5 video使用记录: 1.<video>的基本属性: preload: (预加载)iPhone支持,Android不一定支持; poster: (封面图片)iPhone支持 ...
- System中记录体函数命名怪异
//1019unit System; 中发现记录体函数命名怪异//乍一看,很怪异,其实是结构体里面 的变量后面直接写 函数类型了.不像传统先定义T***Event = procedure(S ...
- 从OOP的角度看Golang
资料来源 https://github.com/luciotato/golang-notes/blob/master/OOP.md?hmsr=toutiao.io&utm_medium=tou ...
- XmlRpc.net 入参结构体嵌套的转义操作
项目使用C#开发,需要使用XmlRpc和Linux服务器端交互,用的是XmlRpc.net. 普通的程序调用入参和出差都没有问题,今天遇到入参结构体嵌套,结果 args 入参在服务器端不能解析.抓包数 ...
- BZOJ1129 : [POI2008]Per
枚举LCP,假设前$i-1$个都相同.那么后面$n-i$个数可以随意排列,第$i$个位置可以填的方案数为后面小于$a_i$的数字个数,树状数组维护. 同时为了保证本质不同,方案数需要除以每个数字的个数 ...
- ubuntu下安装了express2.5.8,如何更新它?
在ubuntu上通过apt-get install node-express,结果发现它的版本是2.5.8. 想安装express4.0+的版本,一直不能正确安装,所以一时兴起,打算先删掉它,再重新安 ...
- weex image
weex 的image用来渲染图片, 可以使用img作为它的别名. 需要注意的是,他的长度可宽度必须指定, 不然它是不会工作的. 它没有任何的子组件. 有两个属性: src 用来指定图片的地址图片. ...
- Linux软件安装
#配置/etc/apt/sources.list 通过root权限修改/etc/apt/sources.list $ su #输入密码进入root权限 $ chmod 0666 /etc/apt/so ...