通过表达式树把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表达式的参数类型可以忽略,因为 ...
随机推荐
- Oracle数据类型与.NET中的对应关系
Oracle连接添加的引用不同,会存在数据类型不同以及其他一些差别,就工作中遇到的问题暂时总结下. 两种不同的添加引用语句: (1)System.Data.OracleClient; (2)Oracl ...
- day40 css高级选择器
一.高级选择器 高级选择器分为:后代选择器.子代选择器.并集选择器.交集选择器 后代选择器 使用空格表示后代选择器.顾名思义,父元素的后代(包括儿子,孙子,重孙子) .container p{ col ...
- 论 业务系统 架构 的 简化 (一) 不需要 MQ
MQ , 就是 消息队列(Message Queue), 不知从什么时候起, MQ 被用来 搭建 分布式 业务系统 架构, 一个重要作用 就是用来 “削峰” . 我们 这里 就来 讨论 如何 设 ...
- MINA线程模型
一.三种工作线程: (一) Acceptor thread: 该线程的作用是接收客户端的连接,并将客户端的连接导入到IOProcessor线程模型中.Acceptor thread在调用了Accep ...
- str.replace()和re.sub()/calendar.month_abbr/re.subn()/upper和lower和capitalize/贪婪匹配和费贪婪匹配/re.S和re.DOTALL 笔记
str.replace()可以进行简单的替换 >>> a = 'one.txt, index.py, index.php, index.html, index.js' >> ...
- linux Centos 服务器之间NFS文件共享挂载
linux Centos 6.9服务器之间文件共享挂载 目的:因为服务器设置了负载均衡,多服务器的文件上传必然要同步,这里的目的把服务器1设置为主文件服务器 服务器1:192.168.1.100(共享 ...
- sublime text2+Ctags+Cscope替代Source Insight
说明:以Windows系统下查看C++代码为例.因为Source Insight(以下简称SI)是收费软件,且界面丑陋,所以考虑其替代方案,发现Sublime Text3(以下简称ST3) + Cta ...
- Excel技巧--批量生成指定名称的文件夹
当我要按excel表当中的名字来批量生成文件夹时,手动一个个制作很麻烦(特别是成百上千个时).于是我们可以这么做: 1.在名字右侧建立公式:"MD "&A2. 2.将公式拖 ...
- 黄聪:浓缩的才是精华:浅析GIF格式图片的存储和压缩(转)
http://www.cnblogs.com/qcloud1001/p/6647080.html 成文迪, 在Web前端摸爬滚打的码农一枚,对技术充满热情的菜鸟,致力为手Q的建设添砖加瓦. GIF格式 ...
- Java第01次实验提纲(基本概念+编程环境入门+PTA)
0. 控制台下编译.运行 在Notepad++编写Java程序 学会使用控制台,javac.java 学会使用Notepad++ 参考资料: 控制台-cmd应用基础 扫盲教程 使用命令行编译并运行ja ...