public OrderByPropertyNode(Stack<OrderByQueryNode> nodes)
        {
            if (nodes == null)
            {
                throw Error.ArgumentNull("nodes");
            }

            if (nodes.Count == 0)
            {
                throw new ODataException(SRResources.OrderByNodeNotFound);
            }

            OrderByQueryNode currentNode = nodes.Pop();
            PropertyAccessQueryNode property = currentNode.Expression as PropertyAccessQueryNode;

            if (property == null)
            {
                throw new ODataException(SRResources.OrderByPropertyNotFound);
            }

            Property = property.Property;
            Direction = currentNode.Direction;

            if (nodes.Count > 0)
            {
                ThenBy = new OrderByPropertyNode(nodes);
            }
        }
        private IOrderedQueryable ApplyToCore(IQueryable query)
        {
            // TODO 463999: [OData] Consider moving OrderByPropertyNode to ODataLib
            OrderByPropertyNode props = OrderByPropertyNode.Create(QueryNode);

            bool                   alreadyOrdered  = false;
            IQueryable             querySoFar      = query;
            HashSet <IEdmProperty> propertiesSoFar = new HashSet <IEdmProperty>();

            while (props != null)
            {
                IEdmProperty     property  = props.Property;
                OrderByDirection direction = props.Direction;

                // This check prevents queries with duplicate properties (e.g. $orderby=Id,Id,Id,Id...) from causing stack overflows
                if (propertiesSoFar.Contains(property))
                {
                    throw new ODataException(Error.Format(SRResources.OrderByDuplicateProperty, property.Name));
                }
                propertiesSoFar.Add(property);

                querySoFar     = ExpressionHelpers.OrderBy(querySoFar, property, direction, Context.EntityClrType, alreadyOrdered);
                alreadyOrdered = true;
                props          = props.ThenBy;
            }

            return(querySoFar as IOrderedQueryable);
        }
예제 #3
0
        public OrderByPropertyNode(Stack <OrderByQueryNode> nodes)
        {
            if (nodes == null)
            {
                throw Error.ArgumentNull("nodes");
            }

            if (nodes.Count == 0)
            {
                throw new ODataException(SRResources.OrderByNodeNotFound);
            }

            OrderByQueryNode        currentNode = nodes.Pop();
            PropertyAccessQueryNode property    = currentNode.Expression as PropertyAccessQueryNode;

            if (property == null)
            {
                throw new ODataException(SRResources.OrderByPropertyNotFound);
            }

            Property  = property.Property;
            Direction = currentNode.Direction;

            if (nodes.Count > 0)
            {
                ThenBy = new OrderByPropertyNode(nodes);
            }
        }
        public void Constructor_Initializes_Correctly()
        {
            // Arrange
            Mock<IEdmProperty> mockProperty = new Mock<IEdmProperty>();

            // Act
            OrderByPropertyNode node = new OrderByPropertyNode(mockProperty.Object, OrderByDirection.Descending);

            // Assert
            Assert.ReferenceEquals(mockProperty.Object, node.Property);
            Assert.Equal(OrderByDirection.Descending, node.Direction);
        }
예제 #5
0
        public void Constructor_Initializes_Correctly()
        {
            // Arrange
            Mock <IEdmProperty> mockProperty = new Mock <IEdmProperty>();

            // Act
            OrderByPropertyNode node = new OrderByPropertyNode(mockProperty.Object, OrderByDirection.Descending);

            // Assert
            Assert.ReferenceEquals(mockProperty.Object, node.Property);
            Assert.Equal(OrderByDirection.Descending, node.Direction);
        }
예제 #6
0
        private IOrderedQueryable ApplyToCore(IQueryable query)
        {
            if (Context.ElementClrType == null)
            {
                throw Error.NotSupported(SRResources.ApplyToOnUntypedQueryOption, "ApplyTo");
            }

            ICollection <OrderByNode> nodes = OrderByNodes;

            bool       alreadyOrdered = false;
            IQueryable querySoFar     = query;

            HashSet <IEdmProperty> propertiesSoFar = new HashSet <IEdmProperty>();
            bool orderByItSeen = false;

            foreach (OrderByNode node in nodes)
            {
                OrderByPropertyNode propertyNode = node as OrderByPropertyNode;

                if (propertyNode != null)
                {
                    IEdmProperty     property  = propertyNode.Property;
                    OrderByDirection direction = propertyNode.Direction;

                    // This check prevents queries with duplicate properties (e.g. $orderby=Id,Id,Id,Id...) from causing stack overflows
                    if (propertiesSoFar.Contains(property))
                    {
                        throw new ODataException(Error.Format(SRResources.OrderByDuplicateProperty, property.Name));
                    }
                    propertiesSoFar.Add(property);

                    querySoFar     = ExpressionHelpers.OrderByProperty(querySoFar, property, direction, Context.ElementClrType, alreadyOrdered);
                    alreadyOrdered = true;
                }
                else
                {
                    // This check prevents queries with duplicate nodes (e.g. $orderby=$it,$it,$it,$it...) from causing stack overflows
                    if (orderByItSeen)
                    {
                        throw new ODataException(Error.Format(SRResources.OrderByDuplicateIt));
                    }

                    querySoFar     = ExpressionHelpers.OrderByIt(querySoFar, node.Direction, Context.ElementClrType, alreadyOrdered);
                    alreadyOrdered = true;
                    orderByItSeen  = true;
                }
            }

            return(querySoFar as IOrderedQueryable);
        }
        public void Ctor_TakingOrderByClause_InitializesProperty_Property()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            IEdmProperty property = model.Customer.FindProperty("ID");
            EntityRangeVariable variable = new EntityRangeVariable("it", model.Customer.AsReference(), model.Customers);
            SingleValuePropertyAccessNode node = new SingleValuePropertyAccessNode(new EntityRangeVariableReferenceNode("it", variable), property);
            OrderByClause orderBy = new OrderByClause(thenBy: null, expression: node, direction: OrderByDirection.Ascending, rangeVariable: variable);

            // Act
            OrderByPropertyNode orderByNode = new OrderByPropertyNode(orderBy);

            // Assert
            Assert.Equal(property, orderByNode.Property);
        }
        public void Ctor_TakingOrderByClause_InitializesProperty_Property()
        {
            // Arrange
            CustomersModelWithInheritance model    = new CustomersModelWithInheritance();
            IEdmProperty                  property = model.Customer.FindProperty("ID");
            EntityRangeVariable           variable = new EntityRangeVariable("it", model.Customer.AsReference(), model.Customers);
            SingleValuePropertyAccessNode node     = new SingleValuePropertyAccessNode(new EntityRangeVariableReferenceNode("it", variable), property);
            OrderByClause                 orderBy  = new OrderByClause(thenBy: null, expression: node, direction: OrderByDirection.Ascending, rangeVariable: variable);

            // Act
            OrderByPropertyNode orderByNode = new OrderByPropertyNode(orderBy);

            // Assert
            Assert.Equal(property, orderByNode.Property);
        }
예제 #9
0
        public void CreateCollection_From_OrderByQueryNode_Succeeds()
        {
            // Arrange
            Mock <IEdmTypeReference> mockTypeReference1 = new Mock <IEdmTypeReference>();
            Mock <IEdmTypeReference> mockTypeReference2 = new Mock <IEdmTypeReference>();
            Mock <IEdmProperty>      mockProperty1      = new Mock <IEdmProperty>();

            mockProperty1.SetupGet <IEdmTypeReference>(p => p.Type).Returns(mockTypeReference1.Object);
            Mock <IEdmProperty> mockProperty2 = new Mock <IEdmProperty>();

            mockProperty1.SetupGet <IEdmTypeReference>(p => p.Type).Returns(mockTypeReference2.Object);
            PropertyAccessQueryNode propertyAccessQueryNode1 = new PropertyAccessQueryNode()
            {
                Property = mockProperty1.Object,
            };
            PropertyAccessQueryNode propertyAccessQueryNode2 = new PropertyAccessQueryNode()
            {
                Property = mockProperty2.Object,
            };

            OrderByQueryNode queryNode1 = new OrderByQueryNode()
            {
                Direction  = OrderByDirection.Descending,
                Collection = null,
                Expression = propertyAccessQueryNode1
            };

            OrderByQueryNode queryNode2 = new OrderByQueryNode()
            {
                Direction  = OrderByDirection.Ascending,
                Collection = queryNode1,
                Expression = propertyAccessQueryNode2
            };

            // Act
            ICollection <OrderByPropertyNode> nodes = OrderByPropertyNode.CreateCollection(queryNode2);

            // Assert
            Assert.Equal(2, nodes.Count);
            Assert.ReferenceEquals(mockProperty1.Object, nodes.First().Property);
            Assert.Equal(OrderByDirection.Descending, nodes.First().Direction);

            Assert.ReferenceEquals(mockProperty2.Object, nodes.Last().Property);
            Assert.Equal(OrderByDirection.Ascending, nodes.Last().Direction);
        }
예제 #10
0
        public void CreateCollection_From_OrderByNode_Succeeds()
        {
            // Arrange
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

            builder.EntitySet <SampleClass>("entityset");

            IEdmModel      model = builder.GetEdmModel();
            IEdmEntityType sampleClassEntityType = model.SchemaElements.Single(t => t.Name == "SampleClass") as IEdmEntityType;
            OrderByClause  orderbyNode           = ODataUriParser.ParseOrderBy("Property1 desc, Property2 asc", model, sampleClassEntityType);

            // Act
            ICollection <OrderByPropertyNode> nodes = OrderByPropertyNode.CreateCollection(orderbyNode);

            // Assert
            Assert.Equal(2, nodes.Count);
            Assert.Equal("Property1", nodes.First().Property.Name);
            Assert.Equal(OrderByDirection.Descending, nodes.First().Direction);

            Assert.ReferenceEquals("Property2", nodes.Last().Property.Name);
            Assert.Equal(OrderByDirection.Ascending, nodes.Last().Direction);
        }
예제 #11
0
        private IOrderedQueryable ApplyToCore(IQueryable query, ODataQuerySettings querySettings)
        {
            if (Context.ElementClrType == null)
            {
                throw Error.NotSupported(SRResources.ApplyToOnUntypedQueryOption, "ApplyTo");
            }

            ICollection <OrderByNode> nodes = OrderByNodes;

            bool       alreadyOrdered = false;
            IQueryable querySoFar     = query;

            HashSet <IEdmProperty> propertiesSoFar = new HashSet <IEdmProperty>();
            bool orderByItSeen = false;

            foreach (OrderByNode node in nodes)
            {
                OrderByPropertyNode propertyNode = node as OrderByPropertyNode;

                if (propertyNode != null)
                {
                    IEdmProperty     property  = propertyNode.Property;
                    OrderByDirection direction = propertyNode.Direction;

                    // This check prevents queries with duplicate properties (e.g. $orderby=Id,Id,Id,Id...) from causing stack overflows
                    if (propertiesSoFar.Contains(property))
                    {
                        throw new ODataException(Error.Format(SRResources.OrderByDuplicateProperty, property.Name));
                    }
                    propertiesSoFar.Add(property);

                    if (propertyNode.OrderByClause != null)
                    {
                        // Ensure we have decided how to handle null propagation
                        ODataQuerySettings updatedSettings = querySettings;
                        if (querySettings.HandleNullPropagation == HandleNullPropagationOption.Default)
                        {
                            updatedSettings = new ODataQuerySettings(updatedSettings);
                            updatedSettings.HandleNullPropagation = HandleNullPropagationOptionHelper.GetDefaultHandleNullPropagationOption(query);
                        }

                        LambdaExpression orderByExpression =
                            FilterBinder.Bind(propertyNode.OrderByClause, Context.ElementClrType, Context.Model, updatedSettings);
                        querySoFar = ExpressionHelpers.OrderBy(querySoFar, orderByExpression, direction, Context.ElementClrType, alreadyOrdered);
                    }
                    else
                    {
                        querySoFar = ExpressionHelpers.OrderByProperty(querySoFar, property, direction, Context.ElementClrType, alreadyOrdered);
                    }
                    alreadyOrdered = true;
                }
                else
                {
                    // This check prevents queries with duplicate nodes (e.g. $orderby=$it,$it,$it,$it...) from causing stack overflows
                    if (orderByItSeen)
                    {
                        throw new ODataException(Error.Format(SRResources.OrderByDuplicateIt));
                    }

                    querySoFar     = ExpressionHelpers.OrderByIt(querySoFar, node.Direction, Context.ElementClrType, alreadyOrdered);
                    alreadyOrdered = true;
                    orderByItSeen  = true;
                }
            }

            return(querySoFar as IOrderedQueryable);
        }