Esempio n. 1
0
        public static Expression <Func <T, bool> > AppendOr <T>(Expression <Func <T, bool> > it, params Expression <Func <T, bool> >[] expressions)
        {
            LambdaExpression    itLambda  = it as LambdaExpression;
            Expression          exp       = itLambda.Body;
            ParameterExpression parameter = itLambda.Parameters[0];

            foreach (Expression expression in expressions)
            {
                LambdaExpression expressionLambda    = expression as LambdaExpression;
                Expression       convertedExpression = LinqRebinder.RebindExpression(expressionLambda.Body, expressionLambda.Parameters[0], parameter);
                exp = Expression.AndAlso(exp, convertedExpression);
            }
            return(Expression.Lambda <Func <T, bool> >(exp, itLambda.Parameters));
        }
Esempio n. 2
0
 private Expression Rebind(Expression <Func <TModel, bool> > expression, ParameterExpression parameter)
 {
     return(LinqRebinder.RebindExpression(expression.Body, expression.Parameters.First(), parameter));
 }
Esempio n. 3
0
        private Expression BuildLinqExpression(ref ParserContext context, IEnumerable <StatementPart> parts, int length)
        {
            foreach (var binaryOperator in binaryOperators)
            {
                var i = 0;
                foreach (var part in parts)
                {
                    if (part.BinaryOperator == binaryOperator)
                    {
                        if (i == 0 || i == length - 1)
                        {
                            break;
                        }
                        var firstOperand  = BuildLinqExpression(ref context, parts.Take(i), i);
                        var secondOperand = BuildLinqExpression(ref context, parts.Skip(i + 1).Take(length - i - 1), length - i - 1);

                        var replacements = new Dictionary <Expression, Expression>
                        {
                            { part.BinaryOperator.Operation.Parameters[0], firstOperand },
                            { part.BinaryOperator.Operation.Parameters[1], secondOperand }
                        };
                        var expression = LinqRebinder.Rebind(part.BinaryOperator.Operation.Body, replacements);
                        return(expression);
                    }
                    i++;
                }
            }

            foreach (var unaryOperator in unaryOperators)
            {
                var i = 0;
                foreach (var part in parts)
                {
                    if (part.UnaryOperator == unaryOperator)
                    {
                        if (part.UnaryOperator.LeftSideOperand)
                        {
                            if (i == 0)
                            {
                                break;
                            }
                            var operand = BuildLinqExpression(ref context, parts.Take(i), i);

                            var replacements = new Dictionary <Expression, Expression>
                            {
                                { part.UnaryOperator.Operation.Parameters[0], operand }
                            };
                            var expression = LinqRebinder.Rebind(part.UnaryOperator.Operation.Body, replacements);
                            return(expression);
                        }
                        else
                        {
                            if (i == length - 1)
                            {
                                break;
                            }
                            var operand = BuildLinqExpression(ref context, parts.Skip(i + 1).Take(length - i - 1), length - i - 1);

                            var replacements = new Dictionary <Expression, Expression>
                            {
                                { part.UnaryOperator.Operation.Parameters[0], operand }
                            };
                            var expression = LinqRebinder.Rebind(part.UnaryOperator.Operation.Body, replacements);
                            return(expression);
                        }
                    }
                    i++;
                }
            }

            {
                var i = 0;
                foreach (var part in parts)
                {
                    if (part.MethodOperator != null)
                    {
                        var replacements = new Dictionary <string, Expression>();
                        for (var j = 0; j < part.SubParts.Count; j++)
                        {
                            var operand          = BuildLinqExpression(ref context, part.SubParts[j]);
                            var expressionString = Expression.ArrayIndex(part.MethodOperator.Operation.Parameters[0], Expression.Constant(j, typeof(int))).ToString();
                            replacements.Add(expressionString, operand);
                        }
                        ;
                        foreach (var parameter in part.MethodOperator.Operation.Parameters)
                        {
                            replacements.Add(parameter.ToString(), Expression.Constant(Array.Empty <double>(), typeof(double[])));
                        }
                        var expressionArrayLengthString = Expression.ArrayLength(part.MethodOperator.Operation.Parameters[0]).ToString();
                        replacements.Add(expressionArrayLengthString, Expression.Constant(part.SubParts.Count, typeof(int)));
                        var expression = LinqRebinder.Rebind(part.MethodOperator.Operation.Body, replacements);
                        return(expression);
                    }
                    i++;
                }
            }

            if (length == 1)
            {
                return(BuildLinqExpression(ref context, parts.First()));
            }

            var tokensStrings = String.Join("", parts.Select(x => x.ToString()));

            throw new MathParserException($"Operator not found in this sequence of expressions {tokensStrings}");
        }
Esempio n. 4
0
        public static Expression <Func <T, bool> > AppendExpressionOnMember <T>(Expression <Func <T, bool> > it, MemberInfo member, params Expression[] expressions)
        {
            PropertyInfo propertyInfo = null;
            FieldInfo    fieldInfo    = null;
            Type         type;

            if (member.MemberType == MemberTypes.Property)
            {
                propertyInfo = (PropertyInfo)member;
                type         = propertyInfo.PropertyType;
            }
            else if (member.MemberType == MemberTypes.Field)
            {
                fieldInfo = (FieldInfo)member;
                type      = fieldInfo.FieldType;
            }
            else
            {
                throw new ArgumentException("Member is not a property or a field");
            }

            LambdaExpression    itLambda  = (LambdaExpression)it;
            Expression          exp       = itLambda.Body;
            ParameterExpression parameter = itLambda.Parameters[0];

            foreach (Expression expression in expressions)
            {
                LambdaExpression expressionLambda = expression as LambdaExpression;

                var  typeDetails = TypeAnalyzer.GetTypeDetail(type);
                Type elementType = null;
                if (type.IsArray)
                {
                    elementType = typeDetails.InnerTypes[0];
                }
                else
                {
                    if (typeDetails.InnerTypes.Count == 1)
                    {
                        elementType = typeDetails.InnerTypes[0];
                    }
                }

                if (elementType != null && typeDetails.IsIEnumerable)
                {
                    Expression memberExpression = member.MemberType == MemberTypes.Property ?
                                                  Expression.Property(parameter, propertyInfo) :
                                                  Expression.Field(parameter, fieldInfo);

                    MethodInfo           anyMethod2Generic = TypeAnalyzer.GetGenericMethodDetail(anyMethod2, elementType).MethodInfo;
                    MethodCallExpression callAny2          = Expression.Call(anyMethod2Generic, memberExpression, expressionLambda);

                    MethodInfo           anyMethod1Generic = TypeAnalyzer.GetGenericMethodDetail(anyMethod1, elementType).MethodInfo;
                    MethodCallExpression callAny1          = Expression.Call(anyMethod1Generic, memberExpression);

                    Expression emptyCheckExpression = Expression.OrElse(Expression.Not(callAny1), callAny2);

                    if (exp.NodeType == ExpressionType.Constant && ((ConstantExpression)exp).Value?.ToString().ToBoolean() == true)
                    {
                        exp = emptyCheckExpression;
                    }
                    else
                    {
                        exp = Expression.AndAlso(exp, emptyCheckExpression);
                    }
                }
                else
                {
                    Expression memberExpression = member.MemberType == MemberTypes.Property ?
                                                  Expression.Property(parameter, propertyInfo) :
                                                  Expression.Field(parameter, fieldInfo);

                    LambdaExpression convertedExpressionLambda = (LambdaExpression)LinqRebinder.RebindExpression(expressionLambda, expressionLambda.Parameters[0], memberExpression);

                    Expression nullCheckExpression = Expression.OrElse(Expression.Equal(memberExpression, Expression.Constant(null)), convertedExpressionLambda.Body);

                    if (exp.NodeType == ExpressionType.Constant && ((ConstantExpression)exp).Value?.ToString().ToBoolean() == true)
                    {
                        exp = nullCheckExpression;
                    }
                    else
                    {
                        exp = Expression.AndAlso(exp, nullCheckExpression);
                    }
                }
            }
            return(Expression.Lambda <Func <T, bool> >(exp, itLambda.Parameters));
        }