/// <summary> /// Parses the segments of a path in the select clause. /// </summary> /// <param name="segments">The segments of the select path.</param> /// <param name="index">The index of the segment to parse.</param> private void ParsePathSegment(string[] segments, int index) { Debug.Assert(segments != null, "segments != null"); Debug.Assert(index >= 0 && index < segments.Length, "index >= 0 && index < segments.Length"); // NOTE: Each path is the name of a property or a series of property names // separated by slash ('/'). The special star ('*') character is only supported at the end of a path. string currentSegment = segments[index].Trim(); if (this.selectedProperties == null) { this.selectedProperties = CreateSelectedPropertiesHashSet(); } bool isStar = string.CompareOrdinal(StarSegment, currentSegment) == 0; bool isLastSegment = index == segments.Length - 1; if (!isLastSegment) { if (isStar) { throw new ODataException(ODataErrorStrings.SelectedPropertiesNode_StarSegmentNotLastSegment); } SelectedPropertiesNode childNode = this.EnsureChildAnnotation(currentSegment); childNode.ParsePathSegment(segments, index + 1); } else { this.selectedProperties.Add(currentSegment); } this.hasWildcard |= isStar; }
/// <summary> /// Parses the segments of a path in the select clause. /// </summary> /// <param name="segments">The segments of the select path.</param> /// <param name="index">The index of the segment to parse.</param> private void ParsePathSegment(string[] segments, int index) { Debug.Assert(segments != null, "segments != null"); Debug.Assert(index >= 0 && index < segments.Length, "index >= 0 && index < segments.Length"); // NOTE: Each path is the name of a property or a series of property names // separated by slash ('/'). The special star ('*') character is only supported at the end of a path. string currentSegment = segments[index].Trim(); bool isStar = string.CompareOrdinal(StarSegment, currentSegment) == 0; int idxLP = currentSegment.IndexOf('('); if (idxLP != -1 && IsValidExpandToken(currentSegment)) { string token = currentSegment.Substring(0, idxLP); SelectedPropertiesNode childNode = this.EnsureChildNode(token, /* isExpandedNavigationProperty */ true); childNode.edmModel = this.edmModel; if (idxLP < currentSegment.Length - 2) { string clause = currentSegment.Substring(idxLP + 1, currentSegment.Length - idxLP - 2).Trim(); if (!String.IsNullOrEmpty(clause)) { // Setup the edm model and structured type for the child node before start parsing the select clause. IEdmNavigationProperty navProp = this.structuredType?.DeclaredNavigationProperties() ?.SingleOrDefault(p => p.Name.Equals(token, StringComparison.Ordinal)); if (navProp?.Type != null) { // navigation property could be structural type or collection of structural type. childNode.structuredType = navProp.Type.Definition.AsElementType() as IEdmStructuredType; } childNode.Parse(clause); } } else { childNode.selectionType = SelectionType.EntireSubtree; } } else { bool isLastSegment = index == segments.Length - 1; if (!isLastSegment) { if (isStar) { throw new ODataException(ODataErrorStrings.SelectedPropertiesNode_StarSegmentNotLastSegment); } SelectedPropertiesNode childNode = this.EnsureChildNode(currentSegment, false); childNode.ParsePathSegment(segments, index + 1); } else { if (this.selectedProperties == null) { this.selectedProperties = CreateSelectedPropertiesHashSet(); } this.selectedProperties.Add(currentSegment); } } this.hasWildcard |= isStar; }