Esempio n. 1
0
        private static Expression MakeAggreagationCondition(FilterNodeModel node, Dictionary <string, ParameterExpression> parameters, IBusinessReflector reflector, Expression parent, Type elementType, Expression filter)
        {
            var expression = parent;

            if (filter != null)
            {
                var whereMethod = typeof(Enumerable).GetMethods().Single(x => x.Name == nameof(Enumerable.Where) &&
                                                                         x.GetParameters().Last().ParameterType.GetGenericArguments().Length == 2);
                whereMethod = whereMethod.MakeGenericMethod(elementType);
                expression  = Expression.Call(null, whereMethod, expression, filter);
            }

            if (node.Operator == FilterOperator.Count)
            {
                var method = typeof(Enumerable).GetMethods().Single(x => x.Name == nameof(Enumerable.Count) && x.GetParameters().Length == 1);
                method     = method.MakeGenericMethod(elementType);
                expression = Expression.Call(null, method, expression);
            }
            else
            {
                var methodName = node.Operator.ToString();
                var selection  = Visit(node.Children[1], parameters, reflector, parent) as LambdaExpression;
                var method     = typeof(Enumerable).GetMethods().Single(x => x.Name == methodName && x.GetParameters().Length == 2 &&
                                                                        x.GetParameters()[1].ParameterType.GetGenericArguments().Last() == selection.ReturnType);
                method     = method.MakeGenericMethod(elementType);
                expression = Expression.Call(null, method, expression, selection);
            }
            return(expression);
        }
        private static Expression VisitOperator(FilterNodeModel node, Dictionary <string, ParameterExpression> parameters, IBusinessReflector reflector, Expression parent)
        {
            var  children = new List <Expression>(node.Children.Length);
            Type type     = null;

            foreach (var child in node.Children)
            {
                if (child.NodeType == FilterNodeType.Constant)
                {
                    children.Add(VisitConstant(child, type));
                }
                else
                {
                    children.Add(Visit(child, parameters, reflector, parent));
                }
                if (children.Count == 1)
                {
                    type = children[0].Type;
                }
            }
            children = UnifyDataTypes(children, null).ToList();
            var simplified = SimplifyEqualToBool(node, children);

            if (simplified != null)
            {
                return(simplified);
            }
            switch (node.Operator)
            {
            case FilterOperator.Contains:
            case FilterOperator.EndsWith:
            case FilterOperator.StartsWith:
                return(MakeStringContainment(node.Operator.Value, children));

            case FilterOperator.Equal:
            case FilterOperator.NotEqual:
            case FilterOperator.IsNull:
            case FilterOperator.IsNotNull:
                return(MakeEquality(node.Operator.Value, children));

            case FilterOperator.GreaterThan:
            case FilterOperator.greaterThanOrEqual:
            case FilterOperator.LessThan:
            case FilterOperator.LessThanOrEqual:
            case FilterOperator.Between:
                if (children[0].Type == typeof(string))
                {
                    return(MakeStringComparison(node.Operator.Value, children));
                }
                return(MakeComparison(node.Operator.Value, children));

            case FilterOperator.Abs:
                return(MakeUnaryArithmetic(node.Operator.Value, children.Single()));

            case FilterOperator.Add:
            case FilterOperator.Multiply:
                return(MakeMultyArithmetic(node.Operator.Value, children));

            case FilterOperator.Subtract:
            case FilterOperator.Divide:
            case FilterOperator.Power:
            case FilterOperator.Log:
                return(MakeBinaryArithmetic(node.Operator.Value, children));

            default:
                throw new NotImplementedException();
            }
        }
Esempio n. 3
0
        private static Expression VisitNavigationList(FilterNodeModel node, Dictionary <string, ParameterExpression> parameters, IBusinessReflector reflector, Expression parent)
        {
            var elementType         = parent.Type.GetGenericArguments().Single();
            LambdaExpression filter = null;

            if (node.Operator != FilterOperator.IsEmpty && node.Operator != FilterOperator.IsNotEmpty && node.Children[0] != null)
            {
                filter = (LambdaExpression)Visit(node.Children[0], parameters, reflector, parent);
                if (filter.ReturnType == typeof(bool?))
                {
                    filter = Expression.Lambda(ConvertType(filter.Body, typeof(bool)), filter.Parameters);
                }
            }

            if (node.Operator == FilterOperator.Count || node.Operator == FilterOperator.Sum || node.Operator == FilterOperator.Average)
            {
                return(MakeAggreagationCondition(node, parameters, reflector, parent, elementType, filter));
            }

            var methodName     = node.Operator == FilterOperator.All ? nameof(Enumerable.All) : nameof(Enumerable.Any);
            var negate         = node.Operator == FilterOperator.None || node.Operator == FilterOperator.IsEmpty;
            var parameterCount = filter == null ? 1 : 2;
            var method         = typeof(Enumerable).GetMethods()
                                 .Single(x => x.Name == methodName && x.GetParameters().Length == parameterCount);

            method = method.MakeGenericMethod(elementType);
            var expression = Expression.Call(method,
                                             parameterCount == 1
                                ? new Expression[] { parent }
                                : new Expression[] { parent, filter });

            if (negate)
            {
                return(Expression.Not(expression));
            }
            return(expression);
        }