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();
  • 相关阅读:
    [Unity UGUI]ScrollRect效果大全
    Lua元表
    [译]使用AssetBundle Manader
    [Unity 设计模式]桥接模式(BridgePattern)
    [Unity 设计模式]IOC依赖倒置
    基于Shader实现的UGUI描边解决方案
    UGUI实现不规则区域点击响应
    使用消息分发机制降低程序中的耦合度
    使用IDA静态分析解密《舰娘Collection》的lua脚本
    定制自己的Unity脚本模板
  • 原文地址:https://www.cnblogs.com/doudouzi/p/13607695.html
Copyright © 2011-2022 走看看