Ejemplo n.º 1
0
        private static Expression <T> Compose <T>(this Expression <T> first, Expression <T> second, Func <Expression, Expression, Expression> merge)
        {
            // build parameter map (from parameters of second to parameters of first)
            var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);

            // replace parameters in the second lambda expression with parameters from the first
            var secondBody = RebindParameterVisitor.ReplaceParameters(map, second.Body);

            // apply composition of lambda expression bodies to parameters from the first expression
            return(Expression.Lambda <T>(merge(first.Body, secondBody), first.Parameters));
        }
Ejemplo n.º 2
0
        public static Expression <T> Compose <T>(
            this Expression <T> first,
            Expression <T> second,
            Func <Expression, Expression, Expression> merge)
        {
            var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] })
                      .ToDictionary(p => p.s, p => p.f);

            var secondBody = RebindParameterVisitor.ReplaceParameters(map, second.Body);

            return(Expression.Lambda <T>(merge(first.Body, secondBody), first.Parameters));
        }
Ejemplo n.º 3
0
        /// <summary>
        ///     Joins two binary lambda expressions using the 'Or' conditional operator.
        /// </summary>
        /// <typeparam name="T">
        ///     The type of the predicate.
        /// </typeparam>
        /// <param name="left">
        ///     The first <see cref="Expression{TDelegate}" />.
        /// </param>
        /// <param name="right">
        ///     The second <see cref="Expression{TDelegate}" />.
        /// </param>
        /// <returns>
        ///     The resulting <see cref="Expression{TDelegate}" /> object that contains the joined
        ///     <see cref="Expression{TDelegate}" /> objects.
        /// </returns>
        public static Expression <Func <T, bool> > Or <T>(this Expression <Func <T, bool> > left, Expression <Func <T, bool> > right)
        {
            Expression <Func <T, bool> > all = t => true;

            if (left == all || right == all)
            {
                return(all);
            }

            var rightExprBody = new RebindParameterVisitor(right.Parameters[0], left.Parameters[0]).Visit(right.Body);

            return(Expression.Lambda <Func <T, bool> >(Expression.OrElse(left.Body, rightExprBody ?? throw new InvalidOperationException()), left.Parameters));
        }
Ejemplo n.º 4
0
        /// <summary>
        ///     Joins two binary lambda expressions using the 'And' conditional operator.
        /// </summary>
        /// <typeparam name="T">
        ///     The type of the predicate.
        /// </typeparam>
        /// <param name="left">
        ///     The left <see cref="Expression{TDelegate}" />.
        /// </param>
        /// <param name="right">
        ///     The right <see cref="Expression{TDelegate}" />.
        /// </param>
        /// <returns>
        ///     The resulting <see cref="Expression{TDelegate}" /> object that contains the joined
        ///     <see cref="Expression{TDelegate}" /> objects.
        /// </returns>
        public static Expression <Func <T, bool> > And <T>(this Expression <Func <T, bool> > left, Expression <Func <T, bool> > right)
        {
            Expression <Func <T, bool> > all = t => true;

            if (Lambda.ExpressionsEqual(left, all))
            {
                return(right);
            }

            if (Lambda.ExpressionsEqual(right, all))
            {
                return(left);
            }

            var rightExprBody = new RebindParameterVisitor(right.Parameters[0], left.Parameters[0]).Visit(right.Body);

            return(Expression.Lambda <Func <T, bool> >(Expression.AndAlso(left.Body, rightExprBody ?? throw new InvalidOperationException()), left.Parameters));
        }
Ejemplo n.º 5
0
        /// <summary> OR </summary>
        public static Expression <Func <T, bool> > Or <T>(
            this Expression <Func <T, bool> > expr1,
            Expression <Func <T, bool> > expr2)
        {
            if (expr1 is null)
            {
                throw new ArgumentNullException(nameof(expr1));
            }
            if (expr2 is null)
            {
                throw new ArgumentNullException(nameof(expr2));
            }

            var expr2Body = new RebindParameterVisitor(expr2.Parameters[0], expr1.Parameters[0])
                            .Visit(expr2.Body);

            return(Expression.Lambda <Func <T, bool> >(
                       Expression.OrElse(expr1.Body, expr2Body), expr1.Parameters));
        }
Ejemplo n.º 6
0
        /// <summary> AND </summary>
        public static Expression <Func <T, bool> > And <T>([NotNull] this Expression <Func <T, bool> > expr1, [NotNull] Expression <Func <T, bool> > expr2)
        {
            var expr2Body = new RebindParameterVisitor(expr2.Parameters[0], expr1.Parameters[0]).Visit(expr2.Body);

            return(Expression.Lambda <Func <T, bool> >(Expression.AndAlso(expr1.Body, expr2Body), expr1.Parameters));
        }
Ejemplo n.º 7
0
        public static Expression <Func <T, bool> > Or <T>(this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2)
        {
            var expr2Body = new RebindParameterVisitor(expr2.Parameters[0], expr1.Parameters[0]).Visit(expr2.Body);

            return(Expression.Lambda <Func <T, bool> >(Expression.OrElse(expr1.Body, expr2Body), expr1.Parameters));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// 建立And查询条件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="leftExpression">左表达式</param>
        /// <param name="rightExpression">右表达式</param>
        /// <returns>组合后的表达式</returns>
        public static Expression <Func <T, bool> > And <T>([NotNull] this Expression <Func <T, bool> > leftExpression, [NotNull] Expression <Func <T, bool> > rightExpression)
        {
            var expr2Body = new RebindParameterVisitor(rightExpression.Parameters[0], leftExpression.Parameters[0]).Visit(rightExpression.Body);

            return(Expression.Lambda <Func <T, bool> >(Expression.AndAlso(leftExpression.Body, expr2Body), leftExpression.Parameters));
        }
Ejemplo n.º 9
0
        /// <summary>
        ///     Joins two binary lambda expressions using the 'Or' conditional operator.
        /// </summary>
        /// <typeparam name="T">
        ///     The type of the predicate.
        /// </typeparam>
        /// <param name="left">
        ///     The first <see cref="Expression{TDelegate}" />.
        /// </param>
        /// <param name="right">
        ///     The second <see cref="Expression{TDelegate}" />.
        /// </param>
        /// <returns>
        ///     The resulting <see cref="Expression{TDelegate}" /> object that contains the joined
        ///     <see cref="Expression{TDelegate}" /> objects.
        /// </returns>
        public static Expression <Func <T, bool> > Or <T>(this Expression <Func <T, bool> > left, Expression <Func <T, bool> > right)
        {
            var leftExprBody = new RebindParameterVisitor(right.Parameters[0], left.Parameters[0]).Visit(right.Body);

            return(Expression.Lambda <Func <T, bool> >(Expression.OrElse(left.Body, leftExprBody ?? throw new InvalidOperationException()), left.Parameters));
        }