SqlDataReader生成动态Lambda表达式
上一扁使用动态lambda表达式来将DataTable转换成实体,比直接用反射快了不少。主要是首行转换的时候动态生成了委托。
后面的转换都是直接调用委托,省去了多次用反射带来的性能损失。
今天在对SqlServer返回的流对象 SqlDataReader 进行处理,也采用动态生成Lambda表达式的方式转换实体。
先上一版代码
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks; namespace Demo1
{
public static class EntityConverter
{
#region
/// <summary>
/// DataTable生成实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dataTable"></param>
/// <returns></returns>
public static List<T> ToList<T>(this DataTable dataTable) where T : class, new()
{
if (dataTable == null || dataTable.Rows.Count <= ) throw new ArgumentNullException("dataTable", "当前对象为null无法生成表达式树");
Func<DataRow, T> func = dataTable.Rows[].ToExpression<T>();
List<T> collection = new List<T>(dataTable.Rows.Count);
foreach (DataRow dr in dataTable.Rows)
{
collection.Add(func(dr));
}
return collection;
} /// <summary>
/// 生成表达式
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dataRow"></param>
/// <returns></returns>
public static Func<DataRow, T> ToExpression<T>(this DataRow dataRow) where T : class, new()
{
if (dataRow == null) throw new ArgumentNullException("dataRow", "当前对象为null 无法转换成实体");
ParameterExpression parameter = Expression.Parameter(typeof(DataRow), "dr");
List<MemberBinding> binds = new List<MemberBinding>();
for (int i = ; i < dataRow.ItemArray.Length; i++)
{
String colName = dataRow.Table.Columns[i].ColumnName;
PropertyInfo pInfo = typeof(T).GetProperty(colName);
if (pInfo == null || !pInfo.CanWrite) continue;
MethodInfo mInfo = typeof(DataRowExtensions).GetMethod("Field", new Type[] { typeof(DataRow), typeof(String) }).MakeGenericMethod(pInfo.PropertyType);
MethodCallExpression call = Expression.Call(mInfo, parameter, Expression.Constant(colName, typeof(String)));
MemberAssignment bind = Expression.Bind(pInfo, call);
binds.Add(bind);
}
MemberInitExpression init = Expression.MemberInit(Expression.New(typeof(T)), binds.ToArray());
return Expression.Lambda<Func<DataRow, T>>(init, parameter).Compile();
}
#endregion
/// <summary>
/// 生成lambda表达式
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="reader"></param>
/// <returns></returns>
public static Func<SqlDataReader, T> ToExpression<T>(this SqlDataReader reader) where T : class, new()
{
if (reader == null || reader.IsClosed || !reader.HasRows) throw new ArgumentException("reader", "当前对象无效");
ParameterExpression parameter = Expression.Parameter(typeof(SqlDataReader), "reader");
List<MemberBinding> binds = new List<MemberBinding>();
for (int i = ; i < reader.FieldCount; i++)
{
String colName = reader.GetName(i);
PropertyInfo pInfo = typeof(T).GetProperty(colName);
if (pInfo == null || !pInfo.CanWrite) continue;
MethodInfo mInfo = reader.GetType().GetMethod("GetFieldValue").MakeGenericMethod(pInfo.PropertyType);
MethodCallExpression call = Expression.Call(parameter, mInfo, Expression.Constant(i));
MemberAssignment bind = Expression.Bind(pInfo, call);
binds.Add(bind);
}
MemberInitExpression init = Expression.MemberInit(Expression.New(typeof(T)), binds.ToArray());
return Expression.Lambda<Func<SqlDataReader, T>>(init, parameter).Compile();
} }
}
在上一篇的基础上增加了 SqlDataReader 的扩展方法
以下代码是调用
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks; namespace Demo1
{
class Program
{
static void Main(string[] args)
{
String conString = "Data Source=.; Initial Catalog=master; Integrated Security=true;";
Func<SqlDataReader, Usr> func = null;
List<Usr> usrs = new List<Usr>();
using (SqlDataReader reader = GetReader(conString, "select object_id 'ID',name 'Name' from sys.objects", CommandType.Text, null))
{
while (reader.Read())
{
if (func == null)
{
func = reader.ToExpression<Usr>();
}
Usr usr = func(reader);
usrs.Add(usr);
}
}
usrs.Clear();
Console.ReadKey();
} public static SqlDataReader GetReader(String conString, String sql, CommandType type, params SqlParameter[] pms)
{
SqlConnection conn = new SqlConnection(conString);
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.CommandType = type;
if (pms != null && pms.Count() > )
{
cmd.Parameters.AddRange(pms);
}
conn.Open();
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
}
class Usr
{
public Int32 ID { get; set; }
public String Name { get; set; }
} }
目前只能处理sqlserver返回的对象,处理其它数据库本来是想增加 DbDataReader 的扩展方法,但发现动态生成lambda表达式的地方出错,所以先将现在的
方案记录下来。
文中如果有不清楚或者有问题的地方请园友指出。谢谢。
原创作品,转载请注明出处:http://www.cnblogs.com/lclblog/p/6711292.html
SqlDataReader生成动态Lambda表达式的更多相关文章
- 生成动态Lambda表达式1
SqlDataReader生成动态Lambda表达式 上一扁使用动态lambda表达式来将DataTable转换成实体,比直接用反射快了不少.主要是首行转换的时候动态生成了委托. 后面的转换都是直接调 ...
- 动态生成C# Lambda表达式
转载:http://www.educity.cn/develop/1407905.html,并整理! 对于C# Lambda的理解我们在之前的文章中已经讲述过了,那么作为Delegate的进化使用,为 ...
- C# 构建动态Lambda表达式
做CURD开发的过程中,通常都会需要GetList,然而查询条件是一个可能变化的需求,如何从容对应需求变化呢? 首先,我们来设计一个套路,尝试以最小的工作量完成一次查询条件的需求变更 1.UI收集查询 ...
- EntityFramework使用动态Lambda表达式筛选数据
public static class PredicateBuilder { public static Expression<Func<T, bool>> True<T ...
- 动态LINQ(Lambda表达式)构建
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; us ...
- C# 动态构建表达式树(一)—— 构建 Where 的 Lambda 表达式
C# 动态构建表达式树(一)-- 构建 Where 的 Lambda 表达式 前言 记得之前同事在做筛选功能的时候提出过一个问题:如果用户传入的条件数量不确定,条件的内容也不确定(大于.小于和等于), ...
- Lambda表达式详解
前言 1.天真热,程序员活着不易,星期天,也要顶着火辣辣的太阳,总结这些东西. 2.夸夸lambda吧:简化了匿名委托的使用,让你让代码更加简洁,优雅.据说它是微软自c#1.0后新增的最重要的功能之一 ...
- lambda表达式-转载
来源:http://www.cnblogs.com/knowledgesea/p/3163725.html 前言 1.天真热,程序员活着不易,星期天,也要顶着火辣辣的太阳,总结这些东西. 2.夸夸 ...
- C# lambda表达式(简单易懂)
前言 1.天真热,程序员活着不易,星期天,也要顶着火辣辣的太阳,总结这些东西. 2.夸夸lambda吧:简化了匿名委托的使用,让你让代码更加简洁,优雅.据说它是微软自c#1.0后新增的最重要的功能之一 ...
随机推荐
- [Qt初级] 解决 中QMainWindow和QDockWidget添加布局失败问题
初接触Qt,使用的教程是陆文周编写的<Qt5开发及实例>一书. 其中有关于QDockWidget.QStackedWidget这些类的介绍和使用实例. 要首先说明的是书上讲的非常的清楚,代 ...
- 利刃 MVVMLight 4:绑定和绑定的各种使用场景
一.绑定: 主要包含元素绑定和非元素绑定两种. 1.元素绑定,是绑定的最简单形式,源对象是WPF的元素,并且源对象的属性是依赖项属性. 根据我们之前的知识 ,依赖项属性具有内置的更改通知支持.所以当我 ...
- ERP实施顾问是干什么的?
ERP实施序列的人员,统称为ERP实施顾问. ERP实施顾问“是把公司的ERP实施作为己任,并投入大量的人力和财力以实现这一目标的群体”.他们精通ERP理论与ERP软件的使用方法,熟练运用项目实施方法 ...
- APICloud使用
APICloud-APP开发平台 [网址:]http://www.apicloud.com/ APICloud studio 下载 打开网址,找到开发者社区->文档->下载->开发工 ...
- 每天一个Linux命令 2
wc 命令用于统计指定文本的行数.字数.字节数.格式为“wc [参数] 文本” . 参数 作 ...
- <context:property-placeholder/>元素
<context:property-placeholder/>元素 PropertyPlaceholderConfigurer实现了BeanFactoryPostProcessor接口,它 ...
- Microsoft Visual Studio 2017 安装过程
工欲善其事必先利其器 Visual Studio 2017 正式版官方下载地址:https://www.visualstudio.com/downloads/ 安装vs2017的时候最好关闭已打开的v ...
- Kali linux learning note
from:http://blog.sina.com.cn/s/blog_40983e5e0101dhz0.html 因为kali linux基于debian 7,当然要把这台Acer 4736 ...
- java利用“映射文件访问”(MapperByteBuffer)处理文件与单纯利用Buffer来处理文件的快慢比较
处理文件是java经常使用的操作,在对一个“大文件”(比如超过64M)进行操作时一点点速度的提高都会带来性能的巨大提升.然而我们经常使用的BufferxxStream,来直接处理大文件时,往往力不从心 ...
- JavaScript 再认识(一):Function调用模式对this的影响
近来,学习了一下<JavaScript精粹>,读到了函数这章,理清了JavaScript中this在不同调用模式下的指向. 1.Function调用模式:Function是JavaScri ...