• 用PredicateBuilder实现Linq动态拼接查询


    在使用Linq查询的时候,特别是如果你在使用Entiry Framwork,有时会遇到动态查询的情况(客户的查询条件是不固定的拼接查询)。
    我们能想到的第一方案应该是拼接SQL,的确这样是可以达到我们的目的的。但这样又会破坏程序的一至性,本来使用Entiry Framwork的目标就是用面向对象的方式操纵数据库,这样我们又要开始写SQL语句了。

    其实我一开始也是这样做的直到有一天我们部门的美女程序员给我介绍LinqKit,我才开始用PredicateBuilder来拼接Predicate委托。

    PredicateBuilder是LinqKit库的一部分,下面是PredicateBuilder源代码:

    using System;
    using System.Linq;
    using System.Linq.Expressions;
    
    namespace LinqUtil
    {
        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<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
                                                                Expression<Func<T, bool>> expr2)
            {
                var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
                return Expression.Lambda<Func<T, bool>>
                      (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
            }
    
            public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
                                                                 Expression<Func<T, bool>> expr2)
            {
                var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
                return Expression.Lambda<Func<T, bool>>
                      (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
            }
        }
    }

    这里主要是介绍PredicateBuilder的使用,如想了解PredicateBuilder具体是怎么实现的可以看看这篇文章:传送门

    引入PredicateBuilder依赖

    • 用VS的NuGet安装LinqKit
    • 直接引用上面的源码

    创建PredicateBuilder对象

    var where = PredicateBuilder.True<TrendStatics>();

    可以理解为创建一个初始化为True的Predicate。

    注意:如果你是要创建一个OR组成的Predicate就不能把它初始化为True因为这样这个表达试永远为True了。

    var where = PredicateBuilder.False<TrendStatics>();

    可以理解为创建一个初始化为False的Predicate。

    注意:如果你是要创建一个AND组成的Predicate就不能把它初始化为False因为这样这个表达试永远为False了。

    PredicateBuilder对象拼接

    现在你可以对Predicate进行各种拼接了

    • 全And:
    • var where = PredicateBuilder.True<int>();
      where = where.And(x => x >= 50);
      where = where.And(x => x <= 70);
      var res = list.Where(where.Compile());
    • 全Or:
    • var list  = Enumerable.Range(1, 100);
      var where = PredicateBuilder.False<int>();
      where = where.Or(x => x == 50);
      where = where.Or(x => x == 70);
      var res = list.Where(where.Compile());
    • 各种组合:
    • var list  = Enumerable.Range(1, 100);
      var where = PredicateBuilder.True<int>();
      where = where.And(x => x >= 50);
      where = where.And(x => x <= 70);
      var subwhere = PredicateBuilder.False<int>();
      subwhere = subwhere.Or(x => x == 60);
      subwhere = subwhere.Or(x => x == 61);
      where = where.And(subwhere);
      var res = list.Where(where.Compile());

    PredicateBuilder对象使用

    • 针对集合Linq查询

    你可以这样用:

    var res = list.Where(where.Compile());

    你还可以这样用:

    var res = list.AsQueryable().Where(where);
    • 针对Entity Framework:
    var res = table.Where(where.Expand());

    转载请注明出处:http://www.cnblogs.com/keitsi/p/5621136.html

  • 相关阅读:
    金蝶K3 账套复制
    silverlight控件如何自适应
    一个使用Jquery写的一个鼠标拖动效果
    如何使用C#开发“类ActiveX组件”
    一个非科班出身程序员的成长历程
    Ubuntu 12.04下LAMP安装配置
    Abp vue项目找不到模块“./app.vue”
    google的分析(analytics)js代码分析以及重写
    javascript实现类似google和msn space的拖拽
    Lucene.Net, SQL Server 2008全文检索, Like模糊查询的一点心得
  • 原文地址:https://www.cnblogs.com/qq52117354/p/7773262.html
Copyright © 2020-2023  润新知