zoukankan      html  css  js  c++  java
  • 将不确定变为确定~表达式树是否可以有个集合,条件过滤有了新方向续(新增了OR和AND查询)

    回到目录

    今天发表了《将不确定变为确定~表达式树是否可以有个集合,条件过滤有了新方向》文章后,马上有朋友问起,如何实现OR查询,如果实现AND查询,事实上它说的可能并不完整,完整的话应该是,“如何实现N个字段进行OR运算和AND运算”呢,没错,我在那篇文章中,条件过滤只是针对单个字段的,是一种AND运算,也是一种条件的过滤机制,即:

    有条件a1,a2,a3,它的过滤方式是先过滤a1,然后在剩下的结果里过滤a2,最后再过滤a3,它相然等同于a1 && a2 && a3,但如果要实现OR运算,我的那个程序就无能为力了,看看我们伟大的JamesJim同志写的这个OR与AND为表达式树实现的扩展方法吧,呵呵 。

     1     /// <summary>
     2     /// 条件建立者
     3     /// [单元表达式主要考用用在数据库字段或是其他集合字段中考用直接返回bool查询的]
     4     /// [考用考虑,如果一个内存集合中,考用定义一个属性,属性中有逻辑,例如:return str.Lenght==1;这样的可以用到单元运算符。]
     5     /// </summary>
     6     public static class PredicateBuilder
     7     {
     8         /// <summary>
     9         /// 单元 true 表达式
    10         /// </summary>
    11         /// <typeparam name="T">指定泛型 T</typeparam>
    12         /// <returns>true</returns>
    13         public static Expression<Func<T, bool>> True<T>()
    14         {
    15             return item => true;
    16         }
    17 
    18         /// <summary>
    19         /// 单元 false 表达式
    20         /// </summary>
    21         /// <typeparam name="T">指定泛型 T</typeparam>
    22         /// <returns>false</returns>
    23         public static Expression<Func<T, bool>> False<T>()
    24         {
    25             return item => false;
    26         }
    27 
    28         /// <summary>
    29         /// 双元 Or 表达式
    30         /// </summary>
    31         /// <typeparam name="T">指定泛型 T</typeparam>
    32         /// <param name="exprleft">左表达式</param>
    33         /// <param name="exprright">右表达式</param>
    34         /// <returns>返回合并表达式</returns>
    35         public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> exprleft, Expression<Func<T, bool>> exprright)
    36         {
    37             var invokedExpr = Expression.Invoke(exprright, exprleft.Parameters.Cast<Expression>());
    38             return Expression.Lambda<Func<T, bool>>(Expression.Or(exprleft.Body, invokedExpr), exprleft.Parameters);
    39         }
    40 
    41         /// <summary>
    42         /// 双元 And 表达式
    43         /// </summary>
    44         /// <typeparam name="T">指定泛型 T</typeparam>
    45         /// <param name="exprleft">左表达式</param>
    46         /// <param name="exprright">右表达式</param>
    47         /// <returns>返回合并表达式</returns>
    48         public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> exprleft, Expression<Func<T, bool>> exprright)
    49         {
    50             var invokedExpr = Expression.Invoke(exprright, exprleft.Parameters.Cast<Expression>());
    51             return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(exprleft.Body, invokedExpr), exprleft.Parameters);
    52         }
    53     }

    再配合我的统一条件功能类,进行一下改造:

     1     /// <summary>
     2     /// 功能:条件过滤类
     3     /// 作者:张占岭
     4     /// 日期:2012-6-7
     5     /// </summary>
     6     public class PredicateList<TEntity> : IEnumerable<Expression<Func<TEntity, bool>>> where TEntity : class
     7     {
     8         List<Expression<Func<TEntity, bool>>> expressionList;
     9         public PredicateList()
    10         {
    11             expressionList = new List<Expression<Func<TEntity, bool>>>();
    12         }
    13         /// <summary>
    14         /// 添加到集合
    15         /// </summary>
    16         /// <param name="predicate"></param>
    17         public void Add(Expression<Func<TEntity, bool>> predicate)
    18         {
    19             expressionList.Add(predicate);
    20         }
    21         /// <summary>
    22         /// Or操作添加到集合
    23         /// </summary>
    24         /// <param name="exprleft"></param>
    25         /// <param name="exprright"></param>
    26         public void AddForOr(Expression<Func<TEntity, bool>> exprleft, Expression<Func<TEntity, bool>> exprright)
    27         {
    28             expressionList.Add(exprleft.Or(exprright));
    29         }
    30         /// <summary>
    31         /// And操作添加到集合
    32         /// </summary>
    33         /// <param name="exprleft"></param>
    34         /// <param name="exprright"></param>
    35         public void AddForAnd(Expression<Func<TEntity, bool>> exprleft, Expression<Func<TEntity, bool>> exprright)
    36         {
    37             expressionList.Add(exprleft.And(exprright));
    38         }
    39 
    40         #region IEnumerable 成员
    41 
    42         public IEnumerator GetEnumerator()
    43         {
    44             return expressionList.GetEnumerator();
    45         }
    46 
    47         #endregion
    48 
    49         #region IEnumerable<Expression<Func<TEntity>>> 成员
    50 
    51         IEnumerator<Expression<Func<TEntity, bool>>> IEnumerable<Expression<Func<TEntity, bool>>>.GetEnumerator()
    52         {
    53             return expressionList.GetEnumerator();
    54         }
    55 
    56         #endregion
    57     }

    嘿嘿,这样就可以把一些用到做AND或者OR的条件先进行组成,最后再和其它条件一起过滤,就OK了,呵呵。

    调用时,可以这样:

    1             PredicateList<UserBases> zzl = new PredicateList<UserBases>();
    2             Expression<Func<UserBases, bool>> exp_name = i => i.Name.Contains("zzl");
    3             Expression<Func<UserBases, bool>> exp_id = i => i.UserID == 1;
    4             zzl.AddForOr(exp_name, exp_id);
    5             GetModel(zzl).ForEach(i => Console.WriteLine(i.Name));
    6             Console.ReadKey();

    OK,世界上对于i.Name和i.UserID的赋值,是我们在业务上判断过的,在PredicateList中存在的过滤条件就是真实要被过滤的。

    回到目录

  • 相关阅读:
    [总结]FFMPEG视音频编解码零基础学习方法--转
    ffmpeg中swscale 的用法
    FFmpeg解码H264及swscale缩放详解
    C++: std::string 与 Unicode 如何结合?
    SpringBoot-@RequestParam
    SpringBoot --web 应用开发之文件上传
    Java并发编程:线程池的使用
    Executor线程池的最佳线程数量计算
    并发下线程池的最佳数量计算
    根据CPU核心数确定线程池并发线程数
  • 原文地址:https://www.cnblogs.com/lori/p/2541131.html
Copyright © 2011-2022 走看看