/// <summary> /// Binds a <see cref="SyntacticTree"/>. /// </summary> /// <param name="syntax">The query descriptor token to bind.</param> /// <returns>The bound query descriptor.</returns> public ODataUri BindTree(SyntacticTree syntax) { ExceptionUtils.CheckArgumentNotNull(syntax, "syntax"); ExceptionUtils.CheckArgumentNotNull(syntax.Path, "syntax.Path"); // Make a copy of query options since we may consume some of them as we bind the query bindingState.QueryOptions = new List <CustomQueryOptionToken>(syntax.QueryOptions); ODataPath path = null; FilterClause filter = null; OrderByClause orderBy = null; long? skip = null; long? top = null; SelectExpandClause selectExpand = null; InlineCountKind? inlineCount = null; // First bind the path path = ODataPathFactory.BindPath(syntax.Path, this.bindingState.Configuration); // If the path leads to a collection, then create a range variable that represents iterating over the collection var rangeVariable = NodeFactory.CreateImplicitRangeVariable(path); if (rangeVariable != null) { this.bindingState.RangeVariables.Push(rangeVariable); } if (syntax.Filter != null || syntax.OrderByTokens.Any()) { this.bindingState.ImplicitRangeVariable = this.bindingState.RangeVariables.Peek(); } // Apply filter first, then order-by, skip, top, select and expand filter = BindFilter(syntax, rangeVariable); orderBy = BindOrderBy(syntax, rangeVariable, path); skip = BindSkip(syntax, rangeVariable, path); top = BindTop(syntax, rangeVariable, path); selectExpand = BindSelectExpand(syntax, path, this.bindingState.Configuration); inlineCount = BindInlineCount(syntax, path); // Add the remaining query options to the query descriptor. List <QueryNode> boundQueryOptions = MetadataBinder.ProcessQueryOptions(this.bindingState, this.bindMethod); Debug.Assert(bindingState.QueryOptions == null, "this.queryOptions == null"); bindingState.RangeVariables.Pop(); bindingState.ImplicitRangeVariable = null; return(new ODataUri(path, boundQueryOptions, selectExpand, filter, orderBy, skip, top, inlineCount)); }
/// <summary> /// Parses a <paramref name="pathUri"/> into a semantic <see cref="ODataPath"/> object. /// </summary> /// <remarks> /// This is designed to parse the Path of a URL. If it is used to parse paths that are contained /// within other places, such as $filter expressions, then it may not enforce correct rules. /// </remarks> /// <param name="pathUri">The absolute URI which holds the path to parse.</param> /// <returns>An <see cref="ODataPath"/> representing the metadata-bound path expression.</returns> /// <exception cref="ODataException">Throws if the serviceRoot member is null, or if the input path is not an absolute uri.</exception> public ODataPath ParsePath(Uri pathUri) { ExceptionUtils.CheckArgumentNotNull(pathUri, "pathUri"); if (this.configuration.ServiceRoot == null) { throw new ODataException(ODataErrorStrings.UriParser_NeedServiceRootForThisOverload); } if (!pathUri.IsAbsoluteUri) { throw new ODataException(ODataErrorStrings.UriParser_UriMustBeAbsolute(pathUri)); } UriPathParser pathParser = new UriPathParser(this.Settings.PathLimit); var rawSegments = pathParser.ParsePathIntoSegments(pathUri, this.configuration.ServiceRoot); return(ODataPathFactory.BindPath(rawSegments, this.configuration)); }