Esempio n. 1
0
 static PipelineBinder()
 {
     __methodCallBinder = new MethodInfoMethodCallBinder <PipelineBindingContext>();
     __methodCallBinder.Register(new AnyBinder(), AnyBinder.GetSupportedMethods());
     __methodCallBinder.Register(new AverageBinder(), AverageBinder.GetSupportedMethods());
     __methodCallBinder.Register(new CountBinder(), CountBinder.GetSupportedMethods());
     __methodCallBinder.Register(new DistinctBinder(), DistinctBinder.GetSupportedMethods());
     __methodCallBinder.Register(new FirstBinder(), FirstBinder.GetSupportedMethods());
     __methodCallBinder.Register(new GroupByBinder(), GroupByBinder.GetSupportedMethods());
     __methodCallBinder.Register(new GroupByWithResultSelectorBinder(), GroupByWithResultSelectorBinder.GetSupportedMethods());
     __methodCallBinder.Register(new JoinBinder(), JoinBinder.GetSupportedMethods());
     __methodCallBinder.Register(new MaxBinder(), MaxBinder.GetSupportedMethods());
     __methodCallBinder.Register(new MinBinder(), MinBinder.GetSupportedMethods());
     __methodCallBinder.Register(new OfTypeBinder(), OfTypeBinder.GetSupportedMethods());
     __methodCallBinder.Register(new OrderByBinder(), OrderByBinder.GetSupportedMethods());
     __methodCallBinder.Register(new SampleBinder(), SampleBinder.GetSupportedMethods());
     __methodCallBinder.Register(new SelectBinder(), SelectBinder.GetSupportedMethods());
     __methodCallBinder.Register(new SelectManyBinder(), SelectManyBinder.GetSupportedMethods());
     __methodCallBinder.Register(new SingleBinder(), SingleBinder.GetSupportedMethods());
     __methodCallBinder.Register(new SkipBinder(), SkipBinder.GetSupportedMethods());
     __methodCallBinder.Register(new StandardDeviationPopulationBinder(), StandardDeviationPopulationBinder.GetSupportedMethods());
     __methodCallBinder.Register(new StandardDeviationSampleBinder(), StandardDeviationSampleBinder.GetSupportedMethods());
     __methodCallBinder.Register(new SumBinder(), SumBinder.GetSupportedMethods());
     __methodCallBinder.Register(new TakeBinder(), TakeBinder.GetSupportedMethods());
     __methodCallBinder.Register(new ThenByBinder(), ThenByBinder.GetSupportedMethods());
     __methodCallBinder.Register(new WhereBinder(), WhereBinder.GetSupportedMethods());
 }
Esempio n. 2
0
        /// <summary>
        /// Parses an <paramref name="orderBy "/> clause on the given <paramref name="elementType"/>, binding
        /// the text into semantic nodes using the provided model.
        /// </summary>
        /// <param name="orderBy">String representation of the orderby expression.</param>
        /// <param name="configuration">The configuration used for binding.</param>
        /// <param name="elementType">Type that the orderby clause refers to.</param>
        /// <param name="navigationSource">NavigationSource that the elements are from.</param>
        /// <returns>An <see cref="OrderByClause"/> representing the metadata bound orderby expression.</returns>
        private OrderByClause ParseOrderByImplementation(string orderBy, ODataUriParserConfiguration configuration, IEdmType elementType, IEdmNavigationSource navigationSource)
        {
            ExceptionUtils.CheckArgumentNotNull(configuration, "configuration");
            ExceptionUtils.CheckArgumentNotNull(configuration.Model, "model");
            ExceptionUtils.CheckArgumentNotNull(elementType, "elementType");
            ExceptionUtils.CheckArgumentNotNull(orderBy, "orderBy");

            // Get the syntactic representation of the orderby expression
            UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(configuration.Settings.OrderByLimit, configuration.EnableCaseInsensitiveUriFunctionIdentifier);
            var orderByQueryTokens = expressionParser.ParseOrderBy(orderBy);

            // Bind it to metadata
            BindingState state = new BindingState(configuration);

            state.ImplicitRangeVariable = NodeFactory.CreateImplicitRangeVariable(elementType.ToTypeReference(), navigationSource);
            state.RangeVariables.Push(state.ImplicitRangeVariable);
            if (applyClause != null)
            {
                state.AggregatedPropertyNames = applyClause.GetLastAggregatedPropertyNames();
            }

            MetadataBinder binder        = new MetadataBinder(state);
            OrderByBinder  orderByBinder = new OrderByBinder(binder.Bind);
            OrderByClause  orderByClause = orderByBinder.BindOrderBy(state, orderByQueryTokens);

            return(orderByClause);
        }
Esempio n. 3
0
        public void BindOrderByShouldReturnAnOrderByNodeForEachToken()
        {
            var metadataBinder = new MetadataBinder(this.bindingState);

            this.orderbyBinder = new OrderByBinder(metadataBinder.Bind);
            var tokens = GetDummyOrderbyTokenList(7);
            var result = orderbyBinder.BindOrderBy(this.bindingState, tokens);

            Assert.Null(result.ThenBy.ThenBy.ThenBy.ThenBy.ThenBy.ThenBy.ThenBy);
        }
Esempio n. 4
0
        public void BindOrderByShouldOrderByInEasyToConsumeOrder()
        {
            var metadataBinder = new MetadataBinder(this.bindingState);

            this.orderbyBinder = new OrderByBinder(metadataBinder.Bind);
            var tokens = GetDummyOrderbyTokenList(2); // $orderby=prop0, prop1
            var result = orderbyBinder.BindOrderBy(this.bindingState, tokens);

            result.Expression.ShouldBeConstantQueryNode("prop0");
            result.ThenBy.Expression.ShouldBeConstantQueryNode("prop1");
        }
Esempio n. 5
0
        public OrderByBinderTests()
        {
            this.orderbyBinder = new OrderByBinder(FakeBindMethods.BindMethodReturningASinglePrimitive);

            var implicitRangeVariable = new ResourceRangeVariable(ExpressionConstants.It, HardCodedTestModel.GetPersonTypeReference(), HardCodedTestModel.GetPeopleSet());

            this.bindingState = new BindingState(configuration)
            {
                ImplicitRangeVariable = implicitRangeVariable
            };
            this.bindingState.RangeVariables.Push(new BindingState(configuration)
            {
                ImplicitRangeVariable = implicitRangeVariable
            }.ImplicitRangeVariable);
        }
        public void OrderByBinder_Binds_Throws_InputParameters()
        {
            // Arrange
            IOrderByBinder binder = new OrderByBinder();

            // Act & Assert
            ExceptionAssert.ThrowsArgumentNull(() => binder.BindOrderBy(null, null), "orderByClause");

            // Act & Assert
            SingleValueNode expression    = new Mock <SingleValueNode>().Object;
            RangeVariable   range         = new Mock <RangeVariable>().Object;
            OrderByClause   orderByClause = new OrderByClause(null, expression, OrderByDirection.Descending, range);

            ExceptionAssert.ThrowsArgumentNull(() => binder.BindOrderBy(orderByClause, null), "context");
        }
        private static OrderByBinderResult BindOrderBy <T>(string orderBy, IEdmModel model, ODataQuerySettings querySettings = null, IAssemblyResolver assembliesResolver = null)
        {
            Type          elementType   = typeof(T);
            OrderByClause orderByClause = CreateOrderByNode(orderBy, model, elementType);

            Assert.NotNull(orderByClause);

            querySettings = querySettings ?? _defaultSettings;
            QueryBinderContext context = new QueryBinderContext(model, querySettings, elementType)
            {
                AssembliesResolver = assembliesResolver,
            };

            IOrderByBinder orderByBinder = new OrderByBinder();

            return(orderByBinder.BindOrderBy(orderByClause, context));
        }
Esempio n. 8
0
        public void OrderByBinder_BindsComputedPropertyInDollarOrderBy_FromDollarCompute()
        {
            // Arrange
            QueryClause clause = CreateQueryClause("$orderby=Total&$compute=Price mul Qty as Total", _model, typeof(ComputeCustomer));

            ODataQuerySettings querySettings = new ODataQuerySettings();
            IOrderByBinder     binder        = new OrderByBinder();
            QueryBinderContext context       = new QueryBinderContext(_model, querySettings, typeof(ComputeCustomer));

            if (clause.Compute != null)
            {
                context.AddComputedProperties(clause.Compute.ComputedItems);
            }

            // Act
            OrderByBinderResult orderByResult = binder.BindOrderBy(clause.OrderBy, context);

            // Assert
            Assert.Null(orderByResult.ThenBy);
            Assert.Equal(OrderByDirection.Ascending, orderByResult.Direction);
            string resultExpression = ExpressionStringBuilder.ToString(orderByResult.OrderByExpression);

            Assert.Equal("$it => ($it.Price * Convert($it.Qty))", resultExpression);

            IEnumerable <ComputeCustomer> customers = new[]
            {
                new ComputeCustomer {
                    Id = 1, Qty = 3, Price = 5.99
                },
                new ComputeCustomer {
                    Id = 2, Qty = 5, Price = 2.99
                },
                new ComputeCustomer {
                    Id = 3, Qty = 2, Price = 18.01
                },
                new ComputeCustomer {
                    Id = 4, Qty = 4, Price = 9.99
                },
            };

            var orderedResult = OrderByBinderTests.InvokeOrderBy(customers, orderByResult.OrderByExpression, orderByResult.Direction, false);

            Assert.True(new [] { 2, 1, 3, 4 }.SequenceEqual(orderedResult.Select(a => a.Id))); // ordered id
        }
        /// <summary>
        /// Apply $orderby parameter to query.
        /// </summary>
        /// <param name="query">
        /// The OData aware query.
        /// </param>
        /// <param name="orderbyText">
        /// The $orderby parameter text.
        /// </param>
        /// <param name="entitySetName">
        /// The entity set name.
        /// </param>
        /// <typeparam name="T">
        /// The query type param
        /// </typeparam>
        /// <returns>
        /// The <see cref="ODataQuery{T}"/> query with applied order by parameter.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// Argument Null Exception
        /// </exception>
        public static ODataQueryOrdered <T> OrderBy <T>(this ODataQuery <T> query, string orderbyText, string entitySetName = null)
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }
            if (orderbyText == null)
            {
                throw new ArgumentNullException(nameof(orderbyText));
            }

            IEdmModel edmModel = query.EdmModel;

            ODataQueryOptionParser queryOptionParser = GetParser(
                query,
                entitySetName,
                new Dictionary <string, string> {
                { "$orderby", orderbyText }
            });

            ODataSettings settings = query.ServiceProvider.GetRequiredService <ODataSettings>();

            var orderByClause = queryOptionParser.ParseOrderBy();

            orderByClause = TranslateParameterAlias(orderByClause, queryOptionParser);

            ICollection <OrderByNode> nodes = OrderByNode.CreateCollection(orderByClause);

            var validator = new OrderByQueryValidator(settings.DefaultQuerySettings);

            validator.Validate(nodes, settings.ValidationSettings, edmModel);

            IOrderedQueryable <T> result = (IOrderedQueryable <T>)OrderByBinder.OrderApplyToCore(query, settings.QuerySettings, nodes, edmModel);

            return(new ODataQueryOrdered <T>(result, query.ServiceProvider));
        }
Esempio n. 10
0
        /// <summary>
        /// Generate an expand item based on an ExpandTermToken
        /// </summary>
        /// <param name="tokenIn">the expandTerm token to visit</param>
        /// <returns>the expand item for this expand term token.</returns>
        private ExpandedNavigationSelectItem GenerateExpandItem(ExpandTermToken tokenIn)
        {
            ExceptionUtils.CheckArgumentNotNull(tokenIn, "tokenIn");

            // ensure that we're always dealing with a normalized tree
            if (tokenIn.PathToNavProp.NextToken != null && !tokenIn.PathToNavProp.IsNamespaceOrContainerQualified())
            {
                throw new ODataException(ODataErrorStrings.ExpandItemBinder_TraversingANonNormalizedTree);
            }

            PathSegmentToken        currentToken           = tokenIn.PathToNavProp;
            IEdmEntityType          currentLevelEntityType = this.entityType;
            List <ODataPathSegment> pathSoFar         = new List <ODataPathSegment>();
            PathSegmentToken        firstNonTypeToken = currentToken;

            if (currentToken.IsNamespaceOrContainerQualified())
            {
                pathSoFar.AddRange(SelectExpandPathBinder.FollowTypeSegments(currentToken, this.Model, this.Settings.SelectExpandLimit, ref currentLevelEntityType, out firstNonTypeToken));
            }

            IEdmProperty edmProperty = currentLevelEntityType.FindProperty(firstNonTypeToken.Identifier);

            if (edmProperty == null)
            {
                throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyNotDeclared(currentLevelEntityType.FullName(), currentToken.Identifier));
            }

            IEdmNavigationProperty currentNavProp = edmProperty as IEdmNavigationProperty;

            if (currentNavProp == null)
            {
                // the server allowed non-navigation, non-stream properties to be expanded, but then ignored them.
                if (this.Settings.UseWcfDataServicesServerBehavior && !edmProperty.Type.IsStream())
                {
                    return(null);
                }

                throw new ODataException(ODataErrorStrings.ExpandItemBinder_PropertyIsNotANavigationProperty(currentToken.Identifier, currentLevelEntityType.FullName()));
            }

            pathSoFar.Add(new NavigationPropertySegment(currentNavProp, /*entitySet*/ null));
            ODataExpandPath pathToNavProp = new ODataExpandPath(pathSoFar);

            SelectExpandClause subSelectExpand;

            if (tokenIn.ExpandOption != null)
            {
                subSelectExpand = this.GenerateSubExpand(currentNavProp, tokenIn);
            }
            else
            {
                subSelectExpand = BuildDefaultSubExpand();
            }

            subSelectExpand = this.DecorateExpandWithSelect(subSelectExpand, currentNavProp, tokenIn.SelectOption);

            IEdmEntitySet targetEntitySet = null;

            if (this.entitySet != null)
            {
                targetEntitySet = this.entitySet.FindNavigationTarget(currentNavProp);
            }

            // call MetadataBinder to build the filter clause
            FilterClause filterOption = null;

            if (tokenIn.FilterOption != null)
            {
                MetadataBinder binder       = this.BuildNewMetadataBinder(targetEntitySet);
                FilterBinder   filterBinder = new FilterBinder(binder.Bind, binder.BindingState);
                filterOption = filterBinder.BindFilter(tokenIn.FilterOption);
            }

            // call MetadataBinder again to build the orderby clause
            OrderByClause orderbyOption = null;

            if (tokenIn.OrderByOption != null)
            {
                MetadataBinder binder        = this.BuildNewMetadataBinder(targetEntitySet);
                OrderByBinder  orderByBinder = new OrderByBinder(binder.Bind);
                orderbyOption = orderByBinder.BindOrderBy(binder.BindingState, new OrderByToken[] { tokenIn.OrderByOption });
            }

            return(new ExpandedNavigationSelectItem(pathToNavProp, targetEntitySet, filterOption, orderbyOption, tokenIn.TopOption, tokenIn.SkipOption, tokenIn.InlineCountOption, subSelectExpand));
        }