第一种方法:

  1. public static class PredicateExtensions
  2. {
  3. public static Expression<Func<T, bool>> True<T>() { return f => true; }
  4.  
  5. public static Expression<Func<T, bool>> False<T>() { return f => false; }
  6.  
  7. public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expression1,
  8. Expression<Func<T, bool>> expression2)
  9. {
  10. var invokedExpression = Expression.Invoke(expression2, expression1.Parameters
  11. .Cast<Expression>());
  12.  
  13. return Expression.Lambda<Func<T, bool>>(Expression.Or(expression1.Body, invokedExpression),
  14. expression1.Parameters);
  15. }
  16.  
  17. public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1,
  18. Expression<Func<T, bool>> expression2)
  19. {
  20. var invokedExpression = Expression.Invoke(expression2, expression1.Parameters
  21. .Cast<Expression>());
  22.  
  23. return Expression.Lambda<Func<T, bool>>(Expression.And(expression1.Body,
  24. invokedExpression), expression1.Parameters);
  25. }
  26. }

第二种方法:

  1. public static class PredicateBuilder
  2. {
  3.  
  4. public static Expression<Func<T, bool>> True<T>() { return f => true; }
  5. public static Expression<Func<T, bool>> False<T>() { return f => false; }
  6. public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
  7. {
  8. // build parameter map (from parameters of second to parameters of first)
  9. var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
  10.  
  11. // replace parameters in the second lambda expression with parameters from the first
  12. var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
  13.  
  14. // apply composition of lambda expression bodies to parameters from the first expression
  15. return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
  16. }
  17.  
  18. public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
  19. {
  20. return first.Compose(second, Expression.And);
  21. }
  22.  
  23. public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
  24. {
  25. return first.Compose(second, Expression.Or);
  26. }
  27. }
  28.  
  29. public class ParameterRebinder : ExpressionVisitor
  30. {
  31. private readonly Dictionary<ParameterExpression, ParameterExpression> map;
  32.  
  33. public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
  34. {
  35. this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
  36. }
  37.  
  38. public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
  39. {
  40. return new ParameterRebinder(map).Visit(exp);
  41. }
  42.  
  43. protected override Expression VisitParameter(ParameterExpression p)
  44. {
  45. ParameterExpression replacement;
  46. if (map.TryGetValue(p, out replacement))
  47. {
  48. p = replacement;
  49. }
  50. return base.VisitParameter(p);
  51. }
  52. }

注意,经我实际应用,发现第一种方法PredicateExtensions类有个缺陷,就是仅适合在DbDataContext中使用,若用在EntityContext中,则会报错:LINQ to Entities 不支持 LINQ 表达式节点类型“Invoke”。而使用第二种方法则不会有这个问题,至于问题的根源我还没有找到原因,还望高手指教,谢谢!

通过LINQ表达式树动态构建查询条件的更多相关文章

  1. LINQ to SQL 运行时动态构建查询条件

    在进行数据查询时,经常碰到需要动态构建查询条件.使用LINQ实现这个需求可能会比以前拼接SQL语句更麻烦一些.本文介绍了3种运行时动态构建查询条件的方法.本文中的例子最终实现的都是同一个功能,从Nor ...

  2. linq to sql 动态构建查询表达式树

    通过Expression类进行动态构造lamda表达式. 实现了以下几种类型,好了代码说话: public Expression<Func<T, bool>> GetAndLa ...

  3. Linq to Entity 动态拼接查询条件(重点是OR)

    public static class PredicateExtensions { /// <summary> /// 机关函数应用True时:单个AND有效,多个AND有效:单个OR无效 ...

  4. mybatis 使用记录(二) 动态拼接查询条件

    2016-12-16 阅读项目代码时,在项目的xml文件中发现如下写法: SELECT student_user_id FROM tbr_student_class WHERE 1=1 <if ...

  5. Expression表达式树动态查询

    在进行数据列表的查询中,我们通常会使用两种方式进行查询: linq查询 数据库sql语句查询 这样固然可以实现查询,本人之前也都是这么做的,因为查询的条件很少.使用linq,可以将所有的查询条件的属性 ...

  6. Lambda表达式动态组装查询条件

    最近比较闲,年底了,项目也进入尾声:每天就是维护一下系统,整理整理文档,整理知识点,这样才觉得有点意思: 问题 在使用Linq的where()查询的时候,不知道大家是怎么动态组装多个查询条件时,是怎么 ...

  7. C# - LINQ 表达式树

    表达式树(Expression Tree) 表达式树是不可执行的代码,它只是用于表示一种树状的数据结构,树上的每一个节点都表示为某种表达式类型,大概有25种表达式类型,它们都派生自Expression ...

  8. C#使用表达式树动态调用方法并实现99乘法表

    我们在使用C#编程的时候,经常使用反射来动态调用方法,但有时候需要动态的生成方法,下面介绍使用表达式树的方式来自动生成方法,并调用. 首先需要说明什么是表达式,熟悉Linq的程序猿都用过类似于下面的代 ...

  9. 表达式树动态拼接lambda

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

随机推荐

  1. Eclipse中web项目缓存路径

    eclipse运行web项目后, 默认保存到 workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps ecli ...

  2. 第六章 - 图像变换 - 图像拉伸、收缩、扭曲、旋转[2] - 透视变换(cvWarpPerspective)

    透视变换(单应性?)能提供更大的灵活性,但是一个透视投影并不是线性变换,因此所采用的映射矩阵是3*3,且控点变为4个,其他方面与仿射变换完全类似,下面的例程是针对密集变换,稀疏图像变换则采用cvPer ...

  3. SSH使用教程( Bitvise Tunnelier+Chrome+Proxy Switchy)

    前言 网上很多讲解使用Bitvise Tunnelier+Chrome+Proxy Switchy进行SSHFQ操作的教材有所缺失的部分,不太全面,这里重新整理. 本篇博客的主要内容如下: 准备工作 ...

  4. 为EasyUI 的Tab 标签添加右键菜单

    在网上看了很多demo 自己实现了一个效果如下 ps jquery1.7.2 jQuery EasyUI 1.3.6easyui QQ群:15129679 <!doctype html> ...

  5. Activemq消息类型

    Activemq消息类型JMS规范中的消息类型包括TextMessage.MapMessage.ObjectMessage.BytesMessage.和StreamMessage等五种.ActiveM ...

  6. Visual Studio 2010配置OpenGL-1.8

    参考博客 : 安装参考 1. http://blog.csdn.net/mooncircle/article/details/5545448 2. http://www.cnblogs.com/moo ...

  7. CSS3绘制旋转的太极图案(一)

        实现步骤: 基础HTML: <div class="box-taiji"> <div class="circle-01">< ...

  8. arcgis ERROR:000824 该工具未获得许可

    当时上面还说点击000824进入帮助文档,它说是由于扩展功能未勾选,于是我勾上,结果还是不行,后来它说可能是没有许可,于是我把license重新授权了一遍,结果,还是不行 其实,解决方法是在catal ...

  9. twisted 学习笔记二:创建一个简单TCP客户端

    #coding=utf-8 from twisted.internet import reactor,protocol class QuickClient(protocol.Protocol): de ...

  10. 关于Python的web框架

    uliwebhttp://git.oschina.net/limodou/uliweb uliweb 吸取了其他框架的经验,集成了orm.总的来说一般.这个安装后有个exe文件,命令行工具.不绿色.个 ...