在LINQ中如何查询条件不固定,如何合并两个lambda表达式?其中一个方式是LINQ.Dynamic,关于LINQ.Dynamic的简单使用可以参考这篇文章,还有一种方法是利用Expression表达式树,有关表达式树的介绍,可以看这篇文章。

测试代码如下:

public class Phone
{public string Country { get; set; }public string City { get; set; }public string Name { get; set; }
}
public class Person
{public string Name { get; set; }public string Gender { get; set; }public int Age { get; set; }public List<Phone> Phones { get; set; }}
static void Main(string[] args)
{List<Person> PersonLists = new List<Person>(){new Person { Name = "张三",Age = 20,Gender = "男",Phones = new List<Phone> {new Phone { Country = "中国", City = "北京", Name = "小米" },new Phone { Country = "中国",City = "北京",Name = "华为"},new Phone { Country = "中国",City = "北京",Name = "联想"},new Phone { Country = "中国",City = "台北",Name = "魅族"},}},new Person { Name = "松下",Age = 30,Gender = "男",Phones = new List<Phone> {new Phone { Country = "日本",City = "东京",Name = "索尼"},new Phone { Country = "日本",City = "大阪",Name = "夏普"},new Phone { Country = "日本",City = "东京",Name = "松下"},}},new Person { Name = "克里斯",Age = 40,Gender = "男",Phones = new List<Phone> {new Phone { Country = "美国",City = "加州",Name = "苹果"},new Phone { Country = "美国",City = "华盛顿",Name = "三星"},new Phone { Country = "美国",City = "华盛顿",Name = "HTC"}}}};Expression<Func<Person, bool>> lambdaone = ex => ex.Name.Equals("张三");Expression<Func<Person, bool>> lambdatwo = ex => ex.Age == 30;ParameterExpression pa = Expression.Parameter(typeof(Person), "ex");Expression<Func<Person,bool>> newEx = Expression.Lambda<Func<Person,bool>>(Expression.Or(lambdaone.Body, lambdatwo.Body), pa);var Lists = PersonLists.Where(newEx.Compile());Console.WriteLine();Console.Read();
}

在上述代码中,我要构建一个满足两个条件的过滤查询:名字叫张三或者年龄是30。运行结果如下:

结果报错了,说明没有想象的那么简单。原因是即便我的命名是相同的,都是ex,但是两个表达式本质并不是相同的参数ex ,我只是引用了两个不同parameter的lambda表达式的body,然后将这两个body强行给了另一个parameter,具体信息可以这篇文藏

这时候我们需要重写ExpressionVisitor,代码如下:

    public class MyExpressionVisitor : ExpressionVisitor{public ParameterExpression _Parameter { get; set; }public MyExpressionVisitor(ParameterExpression Parameter){_Parameter = Parameter;}protected override Expression VisitParameter(ParameterExpression p){return _Parameter;}public override Expression Visit(Expression node){return base.Visit(node);//Visit会根据VisitParameter()方法返回的Expression修改这里的node变量}}

修改调试代码如下:

Expression<Func<Person, bool>> lambdaone = ex => ex.Name.Equals("张三");
Expression<Func<Person, bool>> lambdatwo = ex => ex.Age == 30;
ParameterExpression pa = Expression.Parameter(typeof(Person), "ex");
MyExpressionVisitor visitor = new MyExpressionVisitor(pa);//统一参数类型
Expression bodyone = visitor.Visit(lambdaone.Body);
Expression bodytwo = visitor.Visit(lambdatwo.Body);
Expression<Func<Person, bool>> newEx = Expression.Lambda<Func<Person, bool>>(Expression.Or(bodyone, bodytwo), pa);
var Lists = PersonLists.Where(newEx.Compile());
foreach (var List in Lists)
{Console.WriteLine(List.Name);
}
Console.Read();

从运行结果来看,是没问题的

第二种方式是利用Expression.Invoke() ,代码如下:

Expression<Func<Person, bool>> lambdaone = ex => ex.Name.Equals("张三");
Expression<Func<Person, bool>> lambdatwo = ex => ex.Age == 30;
// 创建参数表达式
InvocationExpression invocation = Expression.Invoke(lambdaone, lambdatwo.Parameters.Cast<Expression>());
// 创建or运算
BinaryExpression binary = Expression.Or(lambdatwo.Body, invocation);
// 生成lambda表达式
var exp = Expression.Lambda<Func<Person, bool>>(binary, lambdatwo.Parameters);
var Lists = PersonLists.Where(exp.Compile());
foreach (var List in Lists)
{Console.WriteLine(List.Name);
}
Console.Read();

运行结果相同:

C#中合并两个lambda表达式相关推荐

  1. 如何在一个表达式中合并两个字典?

    我有两个Python字典,我想编写一个返回合并的这两个字典的表达式. 如果update()方法返回其结果而不是就地修改dict,则将是我需要的方法. >>> x = {'a': 1, ...

  2. C++11新特性中的匿名函数Lambda表达式的汇编实现分析(二)

    2019独角兽企业重金招聘Python工程师标准>>> C++11新特性中的匿名函数Lambda表达式的汇编实现分析(一) 首先,让我们来看看以&方式进行变量捕获,同样没有参 ...

  3. java 合并两个列表_如何在Java中合并两个列表?

    java 合并两个列表 Merging two lists in Java is often a useful operation. These lists can be ArrayLists or ...

  4. java合并两个set_Java中合并两个集合的方法

    要在JAVA中合并两个集合,代码如下所示的− 示例import java.util.stream.*; import java.util.*; import java.io.*; public cla ...

  5. lambda表达式_在Java 7或更早版本中使用Java 8 Lambda表达式

    lambda表达式 我认为没有人会拒绝Java 8引入的Lambda表达式的有用性.但是,许多项目都停留在Java 7甚至旧版本上. 升级可能既耗时又昂贵. 如果第三方组件与Java 8不兼容,则可能 ...

  6. 在Java 7或更早版本中使用Java 8 Lambda表达式

    我认为没有人会拒绝Java 8引入的Lambda表达式的有用性.但是,许多项目都停留在Java 7甚至旧版本上. 升级可能既耗时又昂贵. 如果第三方组件与Java 8不兼容,则可能根本无法升级. 除此 ...

  7. python中集合所用的reduce_Python中reduce函数和lambda表达式的学习

    reduce函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1.2 个元素进行操作,得到的结果再与第三个数据用 ...

  8. python合并两个数据集_在Python中合并两个数据集

    我有两组x-y数据,它们的x值应该合并.为了说明这一点,第一组如下所示:0.5;3.4 0.8;3.8 0.9;1.2 1.3;1.1 1.9;2.3 第二盘是这样的: ^{pr2}$ 数据在两个单独 ...

  9. access查询两列信息合并输出_如何在Access中合并两个数据表中的数据

    当我们使用Access处理数据时,我们经常需要合并具有相同表结构的两个数据记录.那么如何实现这一功能呢?以下编辑愿与您分享. 工具/材料 Access 操作方法 打开Access软件,新建两个数据表. ...

最新文章

  1. Android 屏幕录制GIF脚本
  2. python怎么批量处理数据的优点_Python数据处理干货,一文带你深入理解pandas的批量处理方式...
  3. android crop 大图,Android-CropView
  4. 在线nltk分词和词性标注
  5. ubuntu下c++编译cpp(包含自定义类的多级调用)
  6. OpenCV之图像混合
  7. Java面试题300道
  8. 群体智能优化算法之萤火虫群优化算法(Glowworm Swarm Optimization,GSO)
  9. 第二章 马尔科夫决策过程和贝尔曼等式-强化学习理论学习与代码实现(强化学习导论第二版)
  10. 关于UE4中VR项目优化小记
  11. Spring——事物操作
  12. markdown如何设置图片大小_cnblogs文章/MarkDown内如何调整图片的宽度?
  13. 头牌知产介绍减肥药商标注册属于哪一类?
  14. 上云节省 35%计算资源,420 个运维人天:运满满实时计算实践和思考
  15. 【Delphi】中使用消息Messages(七)Android 系统消息
  16. 调制解调器通常接在计算机系统,rj45和rj11有何区别
  17. 【第99题】JAVA高级技术-网络编程18(简易聊天室13:聊天室服务端)
  18. 运放的防护,如何避免电气过载(ESO)
  19. 电信和互联网用户个人信息保护规定_你的孩子的个人信息可能被窃取,保护规定来了...
  20. Photoshop使用路径排版美化文字创作图案

热门文章

  1. PHP-Manual的学习----【语言参考】----【类型】-----【对象】
  2. 即时通讯应用战争开打,到底谁能最终定义我们的交流方式?
  3. HTML5——section,article,aside
  4. jQuery之call()方法的使用
  5. 【mongodb系统学习之四】查看mongodb进程
  6. 在装有raid卡的服务器上安装Ubuntu
  7. JBoss5开发web service常见问题
  8. system函数_自学C++基础教程【函数】
  9. vs设计窗口不见了_碳纤维的巅峰:VS沛纳海616V3
  10. SecureCRT配置前--Linux网卡设置