第一种方法:

public static class PredicateExtensions
{
public static Expression<Func<T, bool>> True<T>() { return f => true; } public static Expression<Func<T, bool>> False<T>() { return f => false; } public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expression1,
Expression<Func<T, bool>> expression2)
{
var invokedExpression = Expression.Invoke(expression2, expression1.Parameters
.Cast<Expression>()); return Expression.Lambda<Func<T, bool>>(Expression.Or(expression1.Body, invokedExpression),
expression1.Parameters);
} public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1,
Expression<Func<T, bool>> expression2)
{
var invokedExpression = Expression.Invoke(expression2, expression1.Parameters
.Cast<Expression>()); return Expression.Lambda<Func<T, bool>>(Expression.And(expression1.Body,
invokedExpression), expression1.Parameters);
}
}

第二种方法:

    public static class PredicateBuilder
{ public static Expression<Func<T, bool>> True<T>() { return f => true; }
public static Expression<Func<T, bool>> False<T>() { return f => false; }
public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
{
// build parameter map (from parameters of second to parameters of first)
var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f); // replace parameters in the second lambda expression with parameters from the first
var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body); // apply composition of lambda expression bodies to parameters from the first expression
return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
} public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.And);
} public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.Or);
}
} public class ParameterRebinder : ExpressionVisitor
{
private readonly Dictionary<ParameterExpression, ParameterExpression> map; public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
{
this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
} public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
{
return new ParameterRebinder(map).Visit(exp);
} protected override Expression VisitParameter(ParameterExpression p)
{
ParameterExpression replacement;
if (map.TryGetValue(p, out replacement))
{
p = replacement;
}
return base.VisitParameter(p);
}
}

注意,经我实际应用,发现第一种方法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. Meanshift filter实现简单图片的卡通化效果

        利用Meanshift filter和canny边缘检测的效果,可以实现简单的图片的卡通化效果.简单的说,就是用Meanshift filter的结果减去canny算法的结果得到卡通化的效果. ...

  2. Selenium 3 -how to locate the chromedriver and geckodriver place?

    Maybe you met these exceptions sometimes: 1. Chrome Driver The path to the driver executable must be ...

  3. iOS 多渠道打包 编译脚本

    http://webfrogs.me/2012/09/19/buildipa/http://blog.csdn.net/baxiaxx/article/details/8267295http://ic ...

  4. Android Studio 快捷键 for mac

    Action Mac OS Win/Linux 打开文件 Cmd + shift + O   打开Class文件 Cmd + O   覆写方法 Ctrl + O   生成方法(重写构造.setter ...

  5. Swift编程语言中的方法引用

    由于Apple官方的<The Swift Programming Guide>对Swift编程语言中的方法引用介绍得不多,所以这里将更深入.详细地介绍Swift中的方法引用. Swift与 ...

  6. fio terse输出详解

    fio, the flexible IO tester, is a very useful tool for benchmarking IO performance. It has an option ...

  7. android 左右翻页

    布局: <?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android ...

  8. drupal7 Views Slideshow 简单教程

    一.下载安装(略) 二.内容类型建立(过程略,首页幻灯),字段建立(过程略)主要有2个字段,图片字段 和 指向链接字段 三.view 1.建立一个新的view,名称为frontbanner 显示为内容 ...

  9. cordova混合开发:Android中native调用javascript

    今天学习怎么在java中调用javascript方法,做个记录: 第一种方式,这个最简单: loadUrl("javascript:func1()"); 要注意要在devicere ...

  10. 浅析 mondrian 模式文件 Schema

    1.前言 前面几篇文章一经介绍过saiku.模式文件和MDX的关系.通俗点说模式文件(Schema)就是一个xml,里面定义了一个虚拟立方体,共MDX查询语言使用. 2.模式文件 Schema 最顶层 ...