zoukankan      html  css  js  c++  java
  • Linq to Entity 动态拼接查询条件(重点是OR)

    /// <summary>
    /// linq动态条件
    /// 构造函数使用True时:单个AND有效,多个AND有效;单个OR无效,多个OR无效;混合时写在AND后的OR有效
    /// 构造函数使用False时:单个AND无效,多个AND无效;单个OR有效,多个OR有效;混合时写在OR后面的AND有效
    /// </summary>
    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);
    }
    }

    2.使用(只是例子)

    var predicate = Lib.Linq.PredicateBuilder.False<CompanyExpansionInfo>();
    foreach (var item in input.ChooseMaterials)
    {
    string str = item.ToString();
    predicate = predicate.Or(t => t.ManufacturingMaterials.Contains(str));
    }
    
    expansionlist = expansionlist.Where(predicate);

    如果以上不懂,可尝试使用以下方法

    namespace Lib
    {
        /// <summary>
        /// 合并表达式 And Or  Not扩展
        /// </summary>
        public static class ExpressionExtend
        {
            /// <summary>
            /// 合并表达式 expr1 AND expr2
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="expr1"></param>
            /// <param name="expr2"></param>
            /// <returns></returns>
            public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
            {
                if (expr1 == null)
                    return expr2;
                else if (expr2 == null)
                    return expr1;            
                ParameterExpression newParameter = Expression.Parameter(typeof(T), "c");
                NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter);
                var left = visitor.Replace(expr1.Body);
                var right = visitor.Replace(expr2.Body);
                var body = Expression.And(left, right);
                return Expression.Lambda<Func<T, bool>>(body, newParameter);
            }
            /// <summary>
            /// 合并表达式 expr1 or expr2
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="expr1"></param>
            /// <param name="expr2"></param>
            /// <returns></returns>
            public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
            {
                if (expr1 == null)
                    return expr2;
                else if (expr2 == null)
                    return expr1;
                ParameterExpression newParameter = Expression.Parameter(typeof(T), "c");
                NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter);
                var left = visitor.Replace(expr1.Body);
                var right = visitor.Replace(expr2.Body);
                var body = Expression.Or(left, right);
                return Expression.Lambda<Func<T, bool>>(body, newParameter);
            }
            public static Expression<Func<T, bool>> Not<T>(this Expression<Func<T, bool>> expr)
            {
                if (expr == null)
                    return null;
                var candidateExpr = expr.Parameters[0];
                var body = Expression.Not(expr.Body);
                return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
            }
        }
        /// <summary>
        /// 建立新表达式
        /// </summary>
        internal class NewExpressionVisitor : ExpressionVisitor
        {
            public ParameterExpression _NewParameter { get; private set; }
            public NewExpressionVisitor(ParameterExpression param)
            {
                this._NewParameter = param;
            }
            public Expression Replace(Expression exp)
            {
                return this.Visit(exp);
            }
            protected override Expression VisitParameter(ParameterExpression node)
            {
                return this._NewParameter;
            }
        }
    }
    //实例:
    //Expression<Func<People, bool>> lambda1 = x => x.Age > 5;
    //Expression<Func<People, bool>> lambda2 = x => x.Id > 5;
    //Expression<Func<People, bool>> lambda3 = lambda1.And(lambda2);
    //Expression<Func<People, bool>> lambda4 = lambda1.Or(lambda2);
    //Expression<Func<People, bool>> lambda5 = lambda1.Not();
  • 相关阅读:
    spring data实现自定义的repository实现类,实现跟jpa联通
    SQLYog快捷键大全
    JSP 中EL表达式用法详解
    java中的标记接口
    单元测试中快速执行某个方法
    Spring Boot 以 jar 包方式运行在后台
    Spring Data JPA
    扩展spring data jpa的数据更新方法时注意事项
    在Spring Data JPA 中使用Update Query更新实体类
    高速创建和mysql表相应的java domain实体类
  • 原文地址:https://www.cnblogs.com/doudouzi/p/13607695.html
Copyright © 2011-2022 走看看