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()); }
/// <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); }
/// <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); }
/// <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; }
/// <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; }
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); }
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 }
/// <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; }
/// <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); }
/// <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); }
/// <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)); }
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); }
/// <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; }