示例#1
0
 static string BindOrderByClause(OrderByClause orderByClause)
 {
     string orderby = string.Format("[{0}] {1}", Bind(orderByClause.Expression), GetDirection(orderByClause.Direction));
     if (orderByClause.ThenBy != null)
         orderby += "," + BindOrderByClause(orderByClause.ThenBy);
     return orderby;
 }
 public void OrderByOptionSetCorrectly()
 {
     SingleValuePropertyAccessNode propertyAccessNode = new SingleValuePropertyAccessNode(new ConstantNode(1), HardCodedTestModel.GetPersonNameProp());
     OrderByClause orderBy = new OrderByClause(null, propertyAccessNode, OrderByDirection.Descending, new EntityRangeVariable(ExpressionConstants.It, HardCodedTestModel.GetPersonTypeReference(), HardCodedTestModel.GetPeopleSet()));
     ExpandedNavigationSelectItem expansion = new ExpandedNavigationSelectItem(new ODataExpandPath(new NavigationPropertySegment(ModelBuildingHelpers.BuildValidNavigationProperty(), null)), HardCodedTestModel.GetPeopleSet(), null, null, orderBy, null, null, null, null, null);
     expansion.OrderByOption.Expression.ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonNameProp());
 }
示例#3
0
 /// <summary>
 /// Create a new ODataUri. This contains the semantic meaning of the 
 /// entire uri.
 /// </summary>
 /// <param name="parameterAliasValueAccessor">The ParameterAliasValueAccessor.</param>
 /// <param name="path">The top level path for this uri.</param>
 /// <param name="customQueryOptions">Any custom query options for this uri. Can be null.</param>
 /// <param name="selectAndExpand">Any $select or $expand option for this uri. Can be null.</param>
 /// <param name="filter">Any $filter option for this uri. Can be null.</param>
 /// <param name="orderby">Any $orderby option for this uri. Can be null</param>
 /// <param name="search">Any $search option for this uri. Can be null</param>
 /// <param name="apply">Any $apply option for this uri. Can be null</param>
 /// <param name="skip">Any $skip option for this uri. Can be null.</param>
 /// <param name="top">Any $top option for this uri. Can be null.</param>
 /// <param name="queryCount">Any query $count option for this uri. Can be null.</param>
 internal ODataUri(
     ParameterAliasValueAccessor parameterAliasValueAccessor,
     ODataPath path,
     IEnumerable<QueryNode> customQueryOptions,
     SelectExpandClause selectAndExpand,
     FilterClause filter,
     OrderByClause orderby,
     SearchClause search,
     ApplyClause apply,
     long? skip,
     long? top,
     bool? queryCount)
 {
     this.ParameterAliasValueAccessor = parameterAliasValueAccessor;
     this.Path = path;
     this.CustomQueryOptions = new ReadOnlyCollection<QueryNode>(customQueryOptions.ToList());
     this.SelectAndExpand = selectAndExpand;
     this.Filter = filter;
     this.OrderBy = orderby;
     this.Search = search;
     this.Apply = apply;
     this.Skip = skip;
     this.Top = top;
     this.QueryCount = queryCount;
 }
 //?$orderby=%20PartnerName%20asc,EnterpriseName%20asc
 public OrderByOperatorResolver(OrderByClause orderByClause)
 {
     if (orderByClause != null)
     {
         fields = new List<string>();
         FillList(orderByClause);
     }
 }
        private void FillList(OrderByClause orderByClause)
        {
            var property = orderByClause.Expression as SingleValuePropertyAccessNode;

            string field = string.Format("{0} {1}", property.Property.Name, orderByClause.Direction == OrderByDirection.Ascending ? "asc" : "desc");
            fields.Add(field);

            if (orderByClause.ThenBy != null)
                FillList(orderByClause.ThenBy);
        }
示例#6
0
        /// <summary>
        /// Creates an <see cref="OrderByClause"/>.
        /// </summary>
        /// <param name="thenBy">The next orderby to perform after performing this orderby, can be null in the case of only a single orderby expression.</param>
        /// <param name="expression">The order-by expression. Cannot be null.</param>
        /// <param name="direction">The direction to order.</param>
        /// <param name="rangeVariable">The rangeVariable for the expression which represents a single value from the collection we iterate over. </param>
        /// <exception cref="System.ArgumentNullException">Throws if the input expression or rangeVariable is null.</exception>
        public OrderByClause(OrderByClause thenBy, SingleValueNode expression, OrderByDirection direction, RangeVariable rangeVariable)
        {
            ExceptionUtils.CheckArgumentNotNull(expression, "expression");
            ExceptionUtils.CheckArgumentNotNull(rangeVariable, "parameter");

            this.thenBy = thenBy;
            this.expression = expression;
            this.direction = direction;
            this.rangeVariable = rangeVariable;
        }
        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);
        }
示例#8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OrderByPropertyNode"/> class.
        /// </summary>
        /// <param name="orderByClause">The orderby clause representing property access.</param>
        public OrderByPropertyNode(OrderByClause orderByClause)
        {
            if (orderByClause == null)
            {
                throw Error.ArgumentNull("orderByClause");
            }

            OrderByClause = orderByClause;
            Direction = orderByClause.Direction;

            SingleValuePropertyAccessNode propertyExpression = orderByClause.Expression as SingleValuePropertyAccessNode;
            if (propertyExpression == null)
            {
                throw new ODataException(SRResources.OrderByClauseNotSupported);
            }
            Property = propertyExpression.Property;
        }
示例#9
0
        /// <summary>
        /// Creates a list of <see cref="OrderByNode"/> instances from a linked list of <see cref="OrderByClause"/> instances.
        /// </summary>
        /// <param name="orderByClause">The head of the <see cref="OrderByClause"/> linked list.</param>
        /// <returns>The list of new <see cref="OrderByPropertyNode"/> instances.</returns>
        public static IList<OrderByNode> CreateCollection(OrderByClause orderByClause)
        {
            List<OrderByNode> result = new List<OrderByNode>();
            for (OrderByClause clause = orderByClause; clause != null; clause = clause.ThenBy)
            {
                if (clause.Expression is NonentityRangeVariableReferenceNode || clause.Expression is EntityRangeVariableReferenceNode)
                {
                    result.Add(new OrderByItNode(clause.Direction));
                }
                else
                {
                    result.Add(new OrderByPropertyNode(clause));
                }
            }

            return result;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="OrderByOpenPropertyNode"/> class.
        /// </summary>
        /// <param name="orderByClause">The order by clause for this open property.</param>
        public OrderByOpenPropertyNode(OrderByClause orderByClause)
            : base(orderByClause.Direction)
        {
            if (orderByClause == null)
            {
                throw Error.ArgumentNull("orderByClause");
            }

            OrderByClause = orderByClause;

            var openPropertyExpression = orderByClause.Expression as SingleValueOpenPropertyAccessNode;
            if (openPropertyExpression == null)
            {
                throw new ODataException(SRResources.OrderByClauseNotSupported);
            }
            PropertyName = openPropertyExpression.Name;
        }
示例#11
0
        public static void VerifyOrderByClauseAreEqual(OrderByClause expected, OrderByClause actual, AssertionHandler assert)
        {
            if (expected == null)
            {
                if (actual != null)
                {
                    throw new Exception("Expected no ThenBy, but found one.");
                }
                return;
            }
            
            if (actual == null)
            {
                throw new Exception("Expected a ThenBy, but found none.");
            }

            VeryfyRangeVariablesAreEqual(expected.RangeVariable, actual.RangeVariable, assert);
            VerifyQueryNodesAreEqual(expected.Expression, actual.Expression, assert);
            VerifyOrderByClauseAreEqual(expected.ThenBy, actual.ThenBy, assert);
        }
示例#12
0
        private static void BuildOrderBy()
        {
            var productTypeRef = new EdmEntityTypeReference(V4Model.Product, false);
            var supplierProperty = (IEdmNavigationProperty)V4Model.Product.FindProperty("Supplier");
            var nameProperty = V4Model.Supplier.FindProperty("Name");

            var topIt = new EntityRangeVariable("$it", productTypeRef, V4Model.ProductsSet);
            var topItRef = new EntityRangeVariableReferenceNode("$it", topIt);
            var supplierNavNode = new SingleNavigationNode(supplierProperty, topItRef);
            var nameNode = new SingleValuePropertyAccessNode(supplierNavNode, nameProperty);

            var orderby = new OrderByClause(null, nameNode, OrderByDirection.Ascending, topIt);
            var odataUri = new ODataUri
            {
                Path = new ODataPath(new EntitySetSegment(V4Model.ProductsSet)),
                ServiceRoot = V4Root,
                OrderBy = orderby
            };
            var builder = new ODataUriBuilder(ODataUrlConventions.Default, odataUri);
            Console.WriteLine(builder.BuildUri());
            // http://services.odata.org/V4/OData/OData.svc/Products?$orderby=Supplier%2FName
        }
示例#13
0
        /// <summary>
        /// Processes the specified order-by token.
        /// </summary>
        /// <param name="state">State to use for binding.</param>
        /// <param name="thenBy"> The next OrderBy node, or null if there is no orderby after this.</param>
        /// <param name="orderByToken">The order-by token to bind.</param>
        /// <returns>Returns the combined entityCollection including the ordering.</returns>
        private OrderByClause ProcessSingleOrderBy(BindingState state, OrderByClause thenBy, OrderByToken orderByToken)
        {
            ExceptionUtils.CheckArgumentNotNull(state, "state");
            ExceptionUtils.CheckArgumentNotNull(orderByToken, "orderByToken");

            QueryNode expressionNode = this.bindMethod(orderByToken.Expression);

            // The order-by expressions need to be primitive / enumeration types
            SingleValueNode expressionResultNode = expressionNode as SingleValueNode;
            if (expressionResultNode == null ||
                (expressionResultNode.TypeReference != null && !expressionResultNode.TypeReference.IsODataPrimitiveTypeKind() && !expressionResultNode.TypeReference.IsODataEnumTypeKind() && !expressionResultNode.TypeReference.IsODataTypeDefinitionTypeKind()))
            {
                throw new ODataException(ODataErrorStrings.MetadataBinder_OrderByExpressionNotSingleValue);
            }

            OrderByClause orderByNode = new OrderByClause(
                thenBy,
                expressionResultNode,
                orderByToken.Direction,
                state.ImplicitRangeVariable);

            return orderByNode;
        }
示例#14
0
        /// <summary>
        /// Parses an orderBy clause on the given full Uri, binding
        /// the text into semantic nodes using the constructed mode.
        /// </summary>
        /// <returns>A <see cref="OrderByClause"/> representing the metadata bound orderby expression.</returns>
        public OrderByClause ParseOrderBy()
        {
            if (this.orderByClause != null)
            {
                return this.orderByClause;
            }

            string orderByQuery;
            if (!this.TryGetQueryOption(UriQueryConstants.OrderByQueryOption, out orderByQuery)
                || string.IsNullOrEmpty(orderByQuery)
                || this.targetEdmType == null)
            {
                return null;
            }

            this.orderByClause = ParseOrderByImplementation(orderByQuery, this.Configuration, this.targetEdmType, this.targetNavigationSource);
            return this.orderByClause;
        }
 /// <summary>
 /// Writes a test case for baselining.
 /// </summary>
 /// <param name="node">Node to write to string</param>
 /// <param name="originalOrderBy">Original $orderby string.</param>
 /// <returns>String representation of the output from the URI Parser.</returns>
 internal static string GetTestCaseAndResultString(OrderByClause node, string originalOrderBy)
 {
     return "$orderby = " + originalOrderBy + "\n\n" + ToString(node);
 }
示例#16
0
 /// <summary>
 /// Compares order by query nodes.
 /// </summary>
 /// <param name="left">Left side of comparison</param>
 /// <param name="right">Right side of comparison</param>
 /// <returns>True if equal, otherwise false</returns>
 private bool Compare(OrderByClause left, OrderByClause right)
 {
     if (left.ItemType != right.ItemType) return false;
     if (left.Direction != right.Direction) return false;
     if (!this.Compare(left.ThenBy, right.ThenBy)) return false;
     if (!this.Compare(left.Expression, right.Expression)) return false;
     return this.CompareParameters(left.RangeVariable, right.RangeVariable);
     
 }
示例#17
0
        /// <summary>
        /// Apply thenOrderBy to the given resouce expression
        /// </summary>
        /// <param name="rootExpression"></param>
        /// <param name="entityInstanceType"></param>
        /// <param name="uriParser"></param>
        /// <param name="thenBy"></param>
        /// <returns></returns>
        public static Expression ApplyThenBy(this Expression rootExpression, Type entityInstanceType, ODataUriParser uriParser, OrderByClause thenBy)
        {
            ParameterExpression parameter = Expression.Parameter(entityInstanceType, "it");
            NodeToExpressionTranslator nodeToExpressionTranslator = new NodeToExpressionTranslator()
            {
                ImplicitVariableParameterExpression = parameter,
                UriParser = uriParser,
            };
            Expression orderByNodeExpression = nodeToExpressionTranslator.TranslateNode(thenBy.Expression);

            var keyType = EdmClrTypeUtils.GetInstanceType(thenBy.Expression.TypeReference);
            var method = thenBy.Direction == OrderByDirection.Ascending ? "ThenBy" : "ThenByDescending";
            //ThenBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
            return Expression.Call(
                typeof(Enumerable),
                method,
                new Type[] { entityInstanceType, keyType },
                rootExpression,
                Expression.Lambda(orderByNodeExpression, parameter));
        }
示例#18
0
 public static string BindOrderByQueryOption(OrderByClause orderByClause)
 {
     if (orderByClause == null)
         return string.Empty;
     return "order by " + BindOrderByClause(orderByClause);
 }
        /// <summary>
        /// Write order by clause to string.
        /// </summary>
        /// <param name="node">Node to write to string</param>
        /// <returns>String representation of node.</returns>
        public static string ToString(OrderByClause node)
        {
            if (node != null)
            {
                return tabHelper.Prefix + "OrderByClause" +
                    tabHelper.Indent(() =>
                        tabHelper.Prefix + "Item Type = " + node.ItemType +
                        tabHelper.Prefix + "Direction = " + node.Direction +
                        tabHelper.Prefix + "Range Variable = " + ToStringParameter(node.RangeVariable) +
                        tabHelper.Prefix + "Expression = " + ToString(node.Expression) +
                        tabHelper.Prefix + "Then By = " + ToString(node.ThenBy)
                    );
            }

            return String.Empty;
        }
 public SqlOrderByBinder(OrderByClause orderByClause)
 {
     //TODO: Resolver posteriormente de maneira mais elegante
     if (orderByClause != null)
         Query = new OrderByOperatorResolver(orderByClause);
 }
示例#21
-1
        /// <summary>
        /// Apply orderby to the given resouce expression
        /// </summary>
        /// <param name="rootExpression"></param>
        /// <param name="entityInstanceType"></param>
        /// <param name="uriParser"></param>
        /// <param name="orderByClause"></param>
        /// <returns></returns>
        public static Expression ApplyOrderBy(this Expression rootExpression, Type entityInstanceType, ODataUriParser uriParser, OrderByClause orderByClause)
        {
            ParameterExpression parameter = Expression.Parameter(entityInstanceType, "it");
            NodeToExpressionTranslator nodeToExpressionTranslator = new NodeToExpressionTranslator()
            {
                ImplicitVariableParameterExpression = parameter,
                UriParser = uriParser,
            };

            Expression orderByNodeExpression = nodeToExpressionTranslator.TranslateNode(orderByClause.Expression);

            var keyType = EdmClrTypeUtils.GetInstanceType(orderByClause.Expression.TypeReference);

            if (orderByClause.Expression.TypeReference.IsNullable && keyType.IsValueType)
            {
                keyType = typeof(Nullable<>).MakeGenericType(keyType);
            }

            var method = orderByClause.Direction == OrderByDirection.Ascending ? "OrderBy" : "OrderByDescending";
            //OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
            var expression = Expression.Call(
                typeof(Enumerable),
                method,
                new Type[] { entityInstanceType, keyType },
                rootExpression,
                Expression.Lambda(orderByNodeExpression, parameter)) as Expression;
            var thenBy = orderByClause.ThenBy;
            while (null != thenBy)
            {
                expression = expression.ApplyThenBy(entityInstanceType, uriParser, thenBy);
                thenBy = thenBy.ThenBy;
            }
            return expression;
        }