0

0

ASP.NET中SqlDataReader生成动态Lambda表达式的实例详解

Y2J

Y2J

发布时间:2017-04-27 10:12:09

|

2294人浏览过

|

来源于php中文网

原创

这篇文章主要介绍了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
  /// 
  /// DataTable生成实体
  /// 
  /// 
  /// 
  /// 
  public static List ToList(this DataTable dataTable) where T : class, new()
  {
   if (dataTable == null || dataTable.Rows.Count <= 0) throw new ArgumentNullException("dataTable", "当前对象为null无法生成表达式树");
   Func func = dataTable.Rows[0].ToExpression();
   List collection = new List(dataTable.Rows.Count);
   foreach (DataRow dr in dataTable.Rows)
   {
    collection.Add(func(dr));
   }
   return collection;
  }
  /// 
  /// 生成表达式
  /// 
  /// 
  /// 
  /// 
  public static Func ToExpression(this DataRow dataRow) where T : class, new()
  {
   if (dataRow == null) throw new ArgumentNullException("dataRow", "当前对象为null 无法转换成实体");
   ParameterExpression parameter = Expression.Parameter(typeof(DataRow), "dr");
   List binds = new List();
   for (int i = 0; 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>(init, parameter).Compile();
  }
  #endregion
  /// 
  /// 生成lambda表达式
  /// 
  /// 
  /// 
  /// 
  public static Func ToExpression(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 binds = new List();
   for (int i = 0; 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>(init, parameter).Compile();
  }
 }
}

在上一篇的基础上增加了 SqlDataReader 的扩展方法

Videoleap
Videoleap

Videoleap是一个一体化的视频编辑平台

下载

以下代码是调用

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 func = null;
   List usrs = new List();
   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 = 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() > 0)
   {
    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表达式的地方出错,所以先将现在的

方案记录下来。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

14

2026.01.30

c++ 字符串格式化
c++ 字符串格式化

本专题整合了c++字符串格式化用法、输出技巧、实践等等内容,阅读专题下面的文章了解更多详细内容。

9

2026.01.30

java 字符串格式化
java 字符串格式化

本专题整合了java如何进行字符串格式化相关教程、使用解析、方法详解等等内容。阅读专题下面的文章了解更多详细教程。

12

2026.01.30

python 字符串格式化
python 字符串格式化

本专题整合了python字符串格式化教程、实践、方法、进阶等等相关内容,阅读专题下面的文章了解更多详细操作。

4

2026.01.30

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

20

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

18

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

19

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

3

2026.01.29

Java空对象相关教程合集
Java空对象相关教程合集

本专题整合了Java空对象相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
极客学院Java8新特性视频教程
极客学院Java8新特性视频教程

共17课时 | 3.8万人学习

ASP.NET参考手册
ASP.NET参考手册

共0课时 | 0人学习

传播智客ASP.NET中级系列视频教程
传播智客ASP.NET中级系列视频教程

共33课时 | 6.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号