通过表达式树把datareader和datatable转换为实体
续上两篇文章,使用emit构造dynamic method,把 datareader转换为实体,以避免直接使用反射来实现带来的性能损失。代码看似没有纰漏,但是实际上我在framwork4下运行时,调用 dynamic method时,
系统都会报 “ 找不到方法 ‘?’ ”的错误,没有找到问题所在,网上查了下资料,发现在framwork3.5以上还可以用表达式树动态构造 执行的语句,并动态编译成方法。性能上与emit还是接近,,而且代码精简了许多。
废话不多说,上代码
public class EntityConverter
{
public static Action<T, object> GetSetter<T>(PropertyInfo property)
{
Action<T, object> result = null;
Type type = typeof(T);
string key = type.AssemblyQualifiedName + "_set_" + property.Name;
if (HttpRuntime.Cache.Get(key) == null)
{ //创建 对实体 属性赋值的expression
ParameterExpression parameter = Expression.Parameter(type, "t");
ParameterExpression value = Expression.Parameter(typeof(object), "propertyValue");
MethodInfo setter = type.GetMethod("set_" + property.Name);
MethodCallExpression call = Expression.Call(parameter, setter, Expression.Convert(value, property.PropertyType));
var lambda = Expression.Lambda<Action<T, object>>(call, parameter, value);
result = lambda.Compile();
HttpRuntime.Cache[key] = result;
}
else
{
result = HttpRuntime.Cache[key] as Action<T, object>;
}
return result;
} public static List<T> ToList<T>(DataTable dt) where T : new()
{
List<T> list = new List<T>();
if (dt == null || dt.Rows.Count == 0)
{
return list;
} foreach (DataRow dr in dt.Rows)
{
T t= new T();
foreach (PropertyInfo prop in typeof(T).GetProperties())
{
if (dr.Table.Columns.Contains(prop.Name))
{
GetSetter<T>(prop)(t, dr[prop.Name]);
}
}
list.Add(t);
} return list;
} public static List<T> ToList<T>(IDataReader dr) where T:new()
{
List<T> list = new List<T>();
while (dr.Read())
{
T t = new T();
foreach (PropertyInfo prop in typeof(T).GetProperties())
{
GetSetter<T>(prop)(t, dr[prop.Name]);
}
list.Add(t);
}
return list;
} }
代码还稍微有点粗糙,还可以细化一下,比如 datatable和datareader的字段名称,和对应实体的属性名,可以忽略大小写,目前我的代码是区分的,有兴趣的可以自己优化。
如果你看完了我写的文字还代码,还是一头雾水,可以看看我的上两篇博文。简单说 就是类似orm的核心功能,把通过ado.net组件查询到的数据(datatable,datareader)转换为实体列表 List<T>,
如果你的代码框架还比较古老,又不愿意引入诸如EF,Nhibernate那样的比较大的框架,不妨考虑自己写一个这样的简单的方法。
List<T> list;
using (IDataReader dr = sqlCommand.ExecuteReader(sql)
{
list = EntityConverter.ToList<T>(dr);
}
通过表达式树把datareader和datatable转换为实体的更多相关文章
- 三层架构中bll层把datatable转换为实体model的理解
看了很多人的项目,很多都是用到三层架构,其中BLL层中有一种将DataTable转换为实体的方法.一直没有明白为啥要这样做,今天特意去搜索了一下,如果没有答案我是准备提问,寻求解答了.还好找到一个相关 ...
- .Net工具类--表达式目录树解析DataReader和DataTable
一.概述 在项目中经常会使用SQL去操作数据库,在读取数据的时候返回结果一般是DataReader和DataSet,其中DataaSet里面可以包含多个DataTable. 读取到数据之后,一般情况下 ...
- DataTable转换为实体集合
using System; using System.Collections; using System.Collections.Generic; using System.Data; using S ...
- jQuery find() 搜索所有段落中的后代 C# find() 第一个匹配元素 Func 有返回值 Action是没有返回值 Predicate 只有一个参数且返回值为bool 表达式树Expression
所有p后代span Id为 TotalProject 的 select 标签 的后代 option标签 为选中的 text using System; using System.Collections ...
- C#中DataTable与实体集合通用转换(使用扩展方法)
本案例提供了:把DataRow转换为单个实体.dataTable转换为List泛型支持时间格式转换. 下文的方法都是扩展方法.扩展方法要求写在静态类中,方法也要静态. 它必须在一个非嵌套.非泛型的静态 ...
- 无法将具有语句体的lambda表达式转换为表达式树
很早就碰到了这个问题,当时也没有深入的研究,趁着空闲,遂把这个问题研究清楚. (一)普通案例 下面从一个普通的案例入手,下面准备两个List集合,都是放在内存里面的(需要模拟到远端执行的时候,我们是通 ...
- 轻量级表达式树解析框架Faller
有话说 之前我写了3篇关于表达式树解析的文章 干货!表达式树解析"框架"(1) 干货!表达式树解析"框架"(2) 干货!表达式树解析"框架" ...
- 再谈使用Emit把Datatable转换为对象集合(List<T>)
一.前因和存在的问题 前面我写了一篇<使用Emit把Datatable转换为对象集合(List<T>)>的博文,其实起源于我自己编写的一个orm工具(见前面几篇博文有介绍),里 ...
- 19、lambda表达式树
一.定义: 表达式树又称为表达式目录树,以数据形式表示语言级代码.所有的数据都存储在树结构中,每个结点表示一个表达式(Expression). 二.要点: –Lambda表达式的参数类型可以忽略,因为 ...
随机推荐
- 推荐一篇文章 《为什么C语言不会过时?》
<为什么C语言不会过时?> 文章地址 : https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665515153&a ...
- [转]xargs详解
为什么要用xargs,问题的来源 在工作中经常会接触到xargs命令,特别是在别人写的脚本里面也经常会遇到,但是却很容易与管道搞混淆,本篇会详细讲解到底什么是xargs命令,为什么要用xargs命令以 ...
- Ionic 使用karma进行单元测试
1. 创建Ionic工程 ionic start projectname cd projectname 2.安装karma插件 npm install karma karma-jasmine karm ...
- Hive DDL及DML操作
一.修改表 增加/删除分区 语法结构 ALTER TABLE table_name ADD [IF NOT EXISTS] partition_spec [ LOCATION 'location1' ...
- OpenCV相机标定坐标系详解
在OpenCV中,可以使用calibrateCamera函数,通过多个视角的2D/3D对应,求解出该相机的内参数和每一个视角的外参数. 使用C++接口时的输入参数如下: objectPoints - ...
- Eclipse提交代码到Spark集群上运行
Spark集群master节点: 192.168.168.200 Eclipse运行windows主机: 192.168.168.100 场景: 为了测试在Eclipse上开发的代码在Spa ...
- ALGO-151_蓝桥杯_算法训练_6-2递归求二进制表示位数
记: 进制转换 AC代码: #include <stdio.h> #define K 2 int main(void) { ; scanf("%d",&n); ...
- VBA Dumper v0.1.4.2, 提取office文档中的VBA代码,监查宏病毒恢复代码(演示版
http://club.excelhome.net/thread-970051-1-1.html VBA Dumper 0.1.4.2更新,填补国内同类程序空白 此程序为演示版,可以在无office的 ...
- 求1~n整数中1出现的次数(《剑指offer》面试题43)
题意: 给定一个整数n,求1~n这n个整数中十进制表示中1出现的次数. 思路: 方法1:最直观的是,对于1~n中的每个整数,分别判断n中的1的个数,具体见<剑指offer>.这种方法的时间 ...
- Java 线程转储 [转]
http://www.oschina.net/translate/java-thread-dump java线程转储 java的线程转储可以被定义为JVM中在某一个给定的时刻运行的所有线程的快照.一个 ...