1、Lambda的介绍

  园中已经有很多关于lambda的介绍了。简单来讲就是vs编译器给我带来的语法糖,本质来讲还是匿名函数。在开发中,lambda给我们带来了很多的简便。关于lambda的演变过程可以看 Lambda的演变过程

  在这里简单的写个lambda的写法:

  Func<int, int, int> calculate = (x, y) => { return x + y; };//计算x+y的lambda
  Console.WriteLine(calculate(1, 2).ToString());//输出3
  Console.WriteLine(calculate(2, 5).ToString());//输出7

2、Lambda表达式树:

  System.Linq.Expressions命名空间中包含了代表表达式的各个类,这些类都是继承于Expression这个类,可以通过Expression这个类的静态方法来构建一些表达式树。。表达式树由三部分组成,左边、操作类型、右边 这三部分组成。

  

  这样就构成了一个简单的表达式树了。举个栗子:

  我们构建一个输入一个int类型的参数,判断它是不是大于10的lambda表达式数,那么左边的表达式树就是这个int类型的参数,操作类型就是“大于”,右边表达式树就是常量10.

 ParameterExpression leftExpression = Expression.Parameter(typeof(int), "m");//int类型的,参数名称为m
ConstantExpression rightExpression = Expression.Constant(, typeof(int));//常量表达式树,10
//进行左边是否大于右边的判断
var binaryExpression =Expression.GreaterThan(leftExpression, rightExpression);
Console.WriteLine(binaryExpression.ToString());
var lambda =Expression.Lambda<Func<int,bool>>(binaryExpression, leftExpression).Compile();//构建成lambda表达式
Console.WriteLine(lambda().ToString());

构建一个判断值是否大于10的表达式树

  我们再来构建一个输入三个int类型的参数(a,b,c),先计算a+b,再判断的(a+b)的值是否大于c的表达式树。

  先分析下,

  第一步我们要计算a+b,那么就要先构建一个a+b的表达式树,在这步,左边表达式树是参数a,操作类型是“+”,右边表达式树是参数b。

  第二步,将(a+b)的值与c比较,那么左边表达式树就是第一步构建好的表达式树,操作类型是">"的比较,右边表达式数是参数c。

ParameterExpression left1Expression= Expression.Parameter(typeof(int), "a");//int类型的,参数名称为a
ParameterExpression right1Expression = Expression.Parameter(typeof(int), "b");//int类型的,参数名称为b
var aAndbExpression = Expression.Add(left1Expression, right1Expression);//进行相加拼接
ParameterExpression cExpression= Expression.Parameter(typeof(int), "c");//int类型的,参数名称为c
var finallyExpression = Expression.GreaterThan(aAndbExpression, cExpression);
Console.WriteLine(finallyExpression.ToString());
var finallyLambda= Expression.Lambda<Func<int,int,int, bool>>(finallyExpression, left1Expression, right1Expression, cExpression).Compile();//构建成lambda表达式
Console.WriteLine(finallyLambda(, , ).ToString());

构建输入a,b,c,并判断a+b是否大于c的lambda表达式树

  简单的构建表达式树就讲到这里了。

3、根据lambda表达式树生成对应sqlwhere条件

  先简单来拆分几个简单的lambda表达式树

    internal class User
{
public string Name { get; set; } public string Address { get; set; } public int Age { get; set; } public int Sex { get; set; } public bool IsDelete { get; set; } public DateTime? CreateTime { get; set; }
}

User类

  a、Expression<Func<User, bool>> expression2 = m => m.Age == 10 && m.Age == 1;

    这个表达式树就是先判断Age是否等于10,在判断Age是否等于1,然后再对其结果进行与运算。分解如下:

    1)、m.Age == 10:先是左边是a.Age,这是一个MemberExpression(字段或者属性表达式),表达式树操作类型是==比较,右边是10这个常量表达式树

    2)、与1类似

    3)、将1和2的结果进行与运算

  b、Expression<Func<User, bool>> expression2 = m => GetAge() ? m.Address == "" : m.Age == 1;

private static bool GetAge()
{
return false;
}

获取条件的方法

    这个表达式树是先判断GetAge方法返回的结果是true还是false,true的话就在判断Address是否等于空,false就判断Age是否等于1

    1)、GetAge();条件表达式树()ConditionalExpression。

    2)、m.Address == "",条件表达式树判断为true执行的部分,

    3)、m.Age == 1;条件表达式树判断为false执行的部分,

  就简单的拆分这两个表达式树。

  根据表达式树生成对应的sqlWhere:

int[] ages = new int[] { , , ,  };
Expression<Func<User, bool>> expression2 = m => (m.Age == && m.Address.StartsWith("浙江") && m.Address.Contains("省") && m.Address.EndsWith("省")) || (m.Sex == || "" == m.Address && ages.Contains(m.Age) && m.Age == ages[]);
//Expression<Func<User, bool>> expression2 = m => m.Address.TrimStart() == "11" && m.Name.TrimEnd() == "3434" && m.Age == 1 && m.IsDelete == true;
//Expression<Func<User, bool>> expression2 = m => GetAge() ? m.Address == "" : m.Age == 1; //Expression<Func<User, bool>> expression2 = m => m.Age == 10 && m.Age == 1;
SqlServerVisitor sqlVisitor = new SqlServerVisitor("A.");
var sqlMember = sqlVisitor.GetSqlWhere(expression2.Body);
Console.WriteLine(sqlMember.Item1);
if (sqlMember.Item2 != null)
{
foreach (var item in sqlMember.Item2)
{
Console.WriteLine($"{item?.ParameterName},{item?.Value}");
}
}

表达式树

 源码下载:https://github.com/yjqGitHub/ExpressionResolve.git

如果有哪里写的不对的地方,还请指教,以免我误导了他人。

 

  

将简单的lambda表达式树转为对应的sqlwhere条件的更多相关文章

  1. 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截

    程序猿修仙之路--数据结构之你是否真的懂数组?   数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构  .要想在之后的江湖历练中通关,数据结构必不可少. ...

  2. C# Lambda表达式详解,及Lambda表达式树的创建

    最近由于项目需要,刚刚学完了Action委托和Func<T>委托,发现学完了委托就必须学习lambda表达式,委托和Lambda表达式联合起来,才能充分的体现委托的便利.才能使代码更加简介 ...

  3. 定义通用的可通过lambda表达式树来获取属性信息

    我们一般获取某个类型或对象的属性信息均采用以下几种方法: 一.通过类型来获取属性信息 var p= typeof(People).GetProperty("Age");//获取指定 ...

  4. EntityFramework动态多条件查询与Lambda表达式树

              在常规的信息系统中, 我们有需要动态多条件查询的情况, 例如UI上有多个选择项可供用户选择多条件查询数据. 那么在.net平台Entity Framework下, 我们用Lambd ...

  5. 动态拼接lambda表达式树

    前言 最近在优化同事写的代码(我们的框架用的是dapperLambda),其中有一个这样很普通的场景——界面上提供了一些查询条件框供用户来进行过滤数据.由于dapperLambda按条件查询时是传入表 ...

  6. 用lambda表达式树替代反射

    本节重点不讲反射机制,而是讲lambda表达式树来替代反射中常用的获取属性和方法,来达到相同的效果但却比反射高效. 每个人都知道,用反射调用一个方法或者对属性执行SetValue和GetValue操作 ...

  7. Lambda表达式树解析(下)

    概述 前面章节,总结了Lambda树的构建,那么怎么解析Lambda表达式树那?Lambda表达式是一种委托构造而成,如果能够清晰的解析Lambda表达式树,那么就能够理解Lambda表达式要传递的正 ...

  8. Lambda表达式树构建(上)

    概述 Lambda是C#常用的语句,采用委托等方式,来封装真实的代码块.Lambda其实就是语法糖,是一个匿名函数,是一种高效的类似于函数式编程的表达式,Lambda简化了开发中需要编写的代码量.它可 ...

  9. Lambda表达式树

    1.常量表达式树 Func< + ); 使用表达式树的方式 ConstantExpression a = Expression.Constant(); ConstantExpression b ...

随机推荐

  1. jstree 学习

    最近的项目用到了jstree,因为对官方文档理解不充分,所以很多功能都是在网站上搜索再进行使用的.(我只是大自然的搬运工) 对每一级的节点,右键后出现不同的结果. 在jstree中右键是由 conte ...

  2. Windows as a Service(3)——使用SCCM管理Windows10更新

    Hello 小伙伴们,这是这个系列的第三篇文章,我已经和大家分享了有关于Windows 10服务分支以及利用WSUS管理更新的方式,有兴趣的小伙伴们可以参考下面的链接: Windows as a Se ...

  3. 【ASP.NET Core】运行原理(4):授权

    本系列将分析ASP.NET Core运行原理 [ASP.NET Core]运行原理(1):创建WebHost [ASP.NET Core]运行原理(2):启动WebHost [ASP.NET Core ...

  4. (转)mysql 无法设置外键的原因总结

    在Mysql中创建外键时,经常会遇到问题而失败,这是因为Mysql中还有很多细节需要我们去留意,我自己总结并查阅资料后列出了以下几种常见原因. 1.  两个字段的类型或者大小不严格匹配.例如,如果一个 ...

  5. Discuz uc.key泄露导致代码注入漏洞

    漏洞描述:在Discuz中,uc_key是UC客户端与服务端通信的通信密钥,discuz中的/api/uc.php存在代码写入漏洞,导致黑客可写入恶意代码获取uckey,最终进入网站后台,造成数据泄漏 ...

  6. iOS中的armv7,armv7s,arm64,i386,x86_64

    前言 一般iOS中的armv7.armv7s.arm64.i386.x86_64这些都代表了什么?在Xcode中如何选择? 介绍 armv7.armv7s.arm64都是ARM处理器的指令集. i38 ...

  7. 关于 const 的一点小研究

    在饱受 var 的折磨之后,ES6 终于推出了新的定义变量的方法:let 和 const 和 var 相比,let 和 const 有了自己的作用域,let 用于定义变量,而 const 用于定义常量 ...

  8. postfix : 452 4.3.1 Insufficient system storage

    postfix Error Message: 452 4.3.1 Insufficient system storage --> 空间不足. 但是实际情况是我的各个分区都没有满,只是我的20G ...

  9. SEO的基本概念 和 提交SITEMAP到搜索引擎

    SEO的基本概念 SEO的基本概念 :我们接触的SEO主要就是做搜索引擎的优化,让搜索引擎更好地收录 我们的网站,不管是首页还是内页,都能有很好的收录和排名.那么我们经常用到的SEO的语句是什么呢?小 ...

  10. 总结Oracle8i 的UNDO表空间损坏(ORA-01092及ORA-00600【4193】)情况下的数据库不完全恢复的经历

    服务器断电重启导致备份生产环境的恢复目录库无法进行启动,提示Ora-01092例程终止.强行断开连接 查看跟踪日志: Wed Jan 10 08:41:37 2018 Errors in file d ...