zoukankan      html  css  js  c++  java
  • 用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

  • 相关阅读:
    windows server 2008 R2 安装 sql server 2000 遇到的种种问题
    圆心的VPS记录信息
    无法访问.您可能没有权限使用网络资源.局域网无法访问共享,局域网无法访问打印机的一些方法
    win7 32位 fastcgi模式 运行php
    SpringBoot+JPA实例
    马斯洛的锤子论
    一道算法题
    MySQL源码解读之数据结构LF_HASH
    JS学习专辑外传(1)
    WPF 用DynamicResource动态样式切换
  • 原文地址:https://www.cnblogs.com/qq52117354/p/7773262.html
Copyright © 2011-2022 走看看