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)); }
private Expression Rebind(Expression <Func <TModel, bool> > expression, ParameterExpression parameter) { return(LinqRebinder.RebindExpression(expression.Body, expression.Parameters.First(), parameter)); }
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}"); }
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)); }