Пример #1
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="T:System.Object" /> class.
 /// </summary>
 public PredicateRouteSubset(Route route,
                             Type type,
                             PredicateRouteOptions options,
                             MemberExpression accessor,
                             IPredicateRoutesProvider routes)
     : base(route, type, options, accessor)
 {
     Routes = routes;
 }
Пример #2
0
        private static LambdaExpression Build(IPredicateSchemeProvider scheme,
                                              Type paramType,
                                              IPredicateRoutesProvider schemeRoutes,
                                              IExpression source)
        {
            if (paramType == null)
            {
                throw new ArgumentNullException(nameof(paramType));
            }

            var        factorized = FactorizeExpression(source);
            var        p          = Expression.Parameter(paramType);
            Expression body       = null;

            foreach (var logicalExpression in factorized.Expressions.OfType <ILogicalExpression>()) //Or
            {
                Expression intermediateResult = null;
                foreach (var expression in logicalExpression.Expressions.OfType <RouteExpression>()) //And
                {
                    var routeSubsetExpression = expression as RouteSubsetExpression;
                    if (routeSubsetExpression != null)
                    {
                        var route = schemeRoutes.GetSubsetRoute(expression.Route);
                        if (route == null)
                        {
                            throw new ArgumentException($"Cannot process '{routeSubsetExpression.Route}' subset route");
                        }

                        var subsetOperator = GeSubsetOperator(scheme, route, routeSubsetExpression.Query);
                        if (subsetOperator == null)
                        {
                            var message = $"'{expression.Route}' subset route does not support '{routeSubsetExpression.Query}' operator";
                            throw new ArgumentException(message);
                        }

                        var subExpression = Build(scheme, route.Type, route.Routes, routeSubsetExpression.Subset);

                        var accessor           = ParameterReplacer.Replace(p, route.Accessor);
                        var compiledExpression = subsetOperator.Expression(accessor, subExpression);

                        var operatorExpression = expression.Operator;
                        var sourceType         = compiledExpression.Type;

                        if (operatorExpression != null)
                        {
                            var @operator = GetOperator(scheme, sourceType, route.Options, operatorExpression.Name);
                            if (@operator == null)
                            {
                                var message = $"'{expression.Route}' route does not support '{operatorExpression.Name}' operator";
                                throw new ArgumentException(message);
                            }

                            var stringValue = operatorExpression.Value.Trim('\"').Trim('\'');
                            var value       = scheme.Converters.Convert(stringValue, sourceType);
                            compiledExpression = @operator.Expression(compiledExpression, sourceType, value);
                            if (operatorExpression.Inverted)
                            {
                                compiledExpression = Expression.Not(compiledExpression);
                            }
                        }

                        intermediateResult = intermediateResult == null
                            ? compiledExpression
                            : Expression.AndAlso(intermediateResult, compiledExpression);
                    }
                    else
                    {
                        var route = schemeRoutes.GetRoute(expression.Route);
                        if (route == null)
                        {
                            var message = $"Unknown '{expression.Route}' route in current context";
                            throw new ArgumentException(message);
                        }

                        var @operator = GetOperator(scheme, route.Type, route.Options, expression.Operator.Name);
                        if (@operator == null)
                        {
                            var message = $"'{expression.Route}' route does not support '{expression.Operator.Name}' operator";
                            throw new ArgumentException(message);
                        }

                        var        accessor           = ParameterReplacer.Replace(p, route.Accessor);
                        var        stringValue        = expression.Operator.Value.Trim('\"').Trim('\'');
                        var        value              = scheme.Converters.Convert(stringValue, route.Type);
                        Expression compiledExpression = @operator.Expression(accessor, route.Type, value);

                        if (expression.Operator.Inverted)
                        {
                            compiledExpression = Expression.Not(compiledExpression);
                        }

                        intermediateResult = intermediateResult == null
                            ? compiledExpression
                            : Expression.AndAlso(intermediateResult, compiledExpression);
                    }
                }

                if (intermediateResult != null)
                {
                    body = body == null
                        ? intermediateResult
                        : Expression.OrElse(body, intermediateResult);
                }
            }
            body = body ?? Expression.Constant(true);
            var lambda = Expression.Lambda(body, p);

            return(lambda);
        }