Example #1
0
        /// <summary>
        /// Translate the parameter alias, convert node, returned entity set into OData path segment.
        /// </summary>
        /// <param name="model">The EDM model</param>
        /// <param name="path">The odata path segments</param>
        /// <param name="parameterAliasNodes">The parameter alias</param>
        /// <returns>The translated odata path segments.</returns>
        public static IEnumerable <ODataPathSegment> Translate(IEdmModel model, Semantic.ODataPath path,
                                                               IDictionary <string, SingleValueNode> parameterAliasNodes)
        {
            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }

            if (path == null)
            {
                throw Error.ArgumentNull("path");
            }

            var translator = new ODataPathSegmentTranslator(model, parameterAliasNodes);

            return(path.WalkWith(translator));
        }
Example #2
0
        private ODataPath Parse(string serviceRoot, string odataPath, IServiceProvider requestContainer, bool template)
        {
            ODataUriParser uriParser;
            Uri            serviceRootUri = null;
            Uri            fullUri        = null;
            IEdmModel      model          = requestContainer.GetRequiredService <IEdmModel>();

            if (template)
            {
                uriParser = new ODataUriParser(model, new Uri(odataPath, UriKind.Relative), requestContainer);
                uriParser.EnableUriTemplateParsing = true;
            }
            else
            {
                Contract.Assert(serviceRoot != null);

                serviceRootUri = new Uri(
                    serviceRoot.EndsWith("/", StringComparison.Ordinal)
                        ? serviceRoot
                        : serviceRoot + "/");

                // Concatenate the root and path and create a Uri. Using Uri to build a Uri from
                // a root and relative path changes the casing on .NetCore. However, odataPath may
                // be a full Uri.
                if (!Uri.TryCreate(odataPath, UriKind.Absolute, out fullUri))
                {
                    fullUri = new Uri(serviceRootUri + odataPath);
                }

                // Due to a bug in the System.Uri some relative paths are rejected if they contain
                // a ':' symbol on a position greater than 1024. This careful check should mitigate
                // this problem by encoding these characters before the path is combined with
                // service roor Uri.
                // https://github.com/dotnet/corefx/issues/29011
                if (!Uri.IsWellFormedUriString(odataPath, UriKind.RelativeOrAbsolute) &&
                    odataPath.IndexOf(':') > MaxUriSchemeName)
                {
                    var odataPathColonEncoded = odataPath.Replace(":", "%3A");
                    if (Uri.IsWellFormedUriString(odataPathColonEncoded, UriKind.Relative))
                    {
                        odataPath = odataPathColonEncoded;
                    }
                }

                fullUri   = new Uri(serviceRootUri, odataPath);
                uriParser = new ODataUriParser(model, serviceRootUri, fullUri, requestContainer);
            }

            if (UrlKeyDelimiter != null)
            {
                uriParser.UrlKeyDelimiter = UrlKeyDelimiter;
            }
            else
            {
                uriParser.UrlKeyDelimiter = ODataUrlKeyDelimiter.Slash;
            }

            ODL.ODataPath         path;
            UnresolvedPathSegment unresolvedPathSegment = null;

            ODL.KeySegment id = null;
            try
            {
                path = uriParser.ParsePath();
            }
            catch (ODataUnrecognizedPathException ex)
            {
                if (ex.ParsedSegments != null &&
                    ex.ParsedSegments.Any() &&
                    (ex.ParsedSegments.Last().EdmType is IEdmComplexType ||
                     ex.ParsedSegments.Last().EdmType is IEdmEntityType) &&
                    ex.CurrentSegment != ODataSegmentKinds.Count)
                {
                    if (!ex.UnparsedSegments.Any())
                    {
                        path = new ODL.ODataPath(ex.ParsedSegments);
                        unresolvedPathSegment = new UnresolvedPathSegment(ex.CurrentSegment);
                    }
                    else
                    {
                        // Throw ODataException if there is some segment following the unresolved segment.
                        throw new ODataException(Error.Format(
                                                     SRResources.InvalidPathSegment,
                                                     ex.UnparsedSegments.First(),
                                                     ex.CurrentSegment));
                    }
                }
                else
                {
                    throw;
                }
            }

            if (!template && path.LastSegment is ODL.NavigationPropertyLinkSegment)
            {
                IEdmCollectionType lastSegmentEdmType = path.LastSegment.EdmType as IEdmCollectionType;

                if (lastSegmentEdmType != null)
                {
                    ODL.EntityIdSegment entityIdSegment = null;
                    bool exceptionThrown = false;

                    try
                    {
                        entityIdSegment = uriParser.ParseEntityId();

                        if (entityIdSegment != null)
                        {
                            // Create another ODataUriParser to parse $id, which is absolute or relative.
                            ODataUriParser parser = new ODataUriParser(model, serviceRootUri, entityIdSegment.Id, requestContainer);
                            id = parser.ParsePath().LastSegment as ODL.KeySegment;
                        }
                    }
                    catch (ODataException)
                    {
                        // Exception was thrown while parsing the $id.
                        // We will throw another exception about the invalid $id.
                        exceptionThrown = true;
                    }

                    if (exceptionThrown ||
                        (entityIdSegment != null &&
                         (id == null ||
                          !(id.EdmType.IsOrInheritsFrom(lastSegmentEdmType.ElementType.Definition) ||
                            lastSegmentEdmType.ElementType.Definition.IsOrInheritsFrom(id.EdmType)))))
                    {
                        // System.Net.Http on NetCore does not have the Uri extension method
                        // ParseQueryString(), to avoid a platform-specific call, extract $id manually.
                        string idValue = fullUri.Query;
                        string idParam = "$id=";
                        int    start   = idValue.IndexOf(idParam, StringComparison.OrdinalIgnoreCase);
                        if (start >= 0)
                        {
                            int end = idValue.IndexOf("&", start, StringComparison.OrdinalIgnoreCase);
                            if (end >= 0)
                            {
                                idValue = idValue.Substring(start + idParam.Length, end - 1);
                            }
                            else
                            {
                                idValue = idValue.Substring(start + idParam.Length);
                            }
                        }

                        throw new ODataException(Error.Format(SRResources.InvalidDollarId, idValue));
                    }
                }
            }

            // do validation for the odata path
            path.WalkWith(new DefaultODataPathValidator(model));

            // do segment translator (for example parameter alias, key & function parameter template, etc)
            var segments =
                ODataPathSegmentTranslator.Translate(model, path, uriParser.ParameterAliasNodes).ToList();

            if (unresolvedPathSegment != null)
            {
                segments.Add(unresolvedPathSegment);
            }

            if (!template)
            {
                AppendIdForRef(segments, id);
            }

            return(new ODataPath(segments)
            {
                Path = path
            });
        }
Example #3
0
        /// <summary>
        /// Parse the odata path.
        /// </summary>
        /// <param name="model">The model to use for path parsing.</param>
        /// <param name="serviceRoot">The service root of the OData path.</param>
        /// <param name="odataPath">The OData path to parse.</param>
        /// <param name="template">The flag indicates whether the path is template or not.</param>
        /// <param name="serviceProvider">The service proivder.</param>
        /// <param name="httpContext"></param>
        /// <param name="resolverSettings"></param>
        /// <returns>A parsed representation of the path, or <c>null</c> if the path does not match the model.</returns>
        public static ODataPath Parse(IEdmModel model, string serviceRoot, string odataPath, bool template, IServiceProvider serviceProvider, ODataUriResolverSettings resolverSettings)
        {
            ODL.ODataUriParser uriParser;
            Uri serviceRootUri = null;
            Uri fullUri        = null;
            // TODO: Replace this type.
            //NameValueCollection queryString = null;

            ODataOptions options = serviceProvider.GetRequiredService <IOptions <ODataOptions> >().Value;

            if (template)
            {
                uriParser = new ODL.ODataUriParser(model, new Uri(odataPath, UriKind.Relative), serviceProvider);
                uriParser.EnableUriTemplateParsing = true;
            }
            else
            {
                Contract.Assert(serviceRoot != null);

                serviceRootUri = new Uri(
                    serviceRoot.EndsWith("/", StringComparison.Ordinal) ?
                    serviceRoot :
                    serviceRoot + "/");

                fullUri = new Uri(serviceRootUri, odataPath);
                //queryString = fullUri.ParseQueryString();
                uriParser = new ODL.ODataUriParser(model, serviceRootUri, fullUri, serviceProvider);
            }

            uriParser.Resolver = resolverSettings.CreateResolver();

            if (options.UrlKeyDelimiter != null)
            {
                uriParser.UrlKeyDelimiter = options.UrlKeyDelimiter;
            }
            else
            {
                // ODL changes to use ODataUrlKeyDelimiter.Slash as default value.
                // Web API still uses the ODataUrlKeyDelimiter.Parentheses as default value.
                // Please remove it after fix: https://github.com/OData/odata.net/issues/642
                uriParser.UrlKeyDelimiter = ODataUrlKeyDelimiter.Parentheses;
            }

            ODL.ODataPath         path;
            UnresolvedPathSegment unresolvedPathSegment = null;

            ODL.KeySegment id = null;
            try
            {
                path = uriParser.ParsePath();
            }
            catch (ODL.ODataUnrecognizedPathException ex)
            {
                if (ex.ParsedSegments != null &&
                    ex.ParsedSegments.Any() &&
                    (ex.ParsedSegments.Last().EdmType is IEdmComplexType ||
                     ex.ParsedSegments.Last().EdmType is IEdmEntityType) &&
                    ex.CurrentSegment != ODataSegmentKinds.Count)
                {
                    if (!ex.UnparsedSegments.Any())
                    {
                        path = new ODL.ODataPath(ex.ParsedSegments);
                        unresolvedPathSegment = new UnresolvedPathSegment(ex.CurrentSegment);
                    }
                    else
                    {
                        // Throw ODataException if there is some segment following the unresolved segment.
                        throw new ODataException(Error.Format(
                                                     SRResources.InvalidPathSegment,
                                                     ex.UnparsedSegments.First(),
                                                     ex.CurrentSegment));
                    }
                }
                else
                {
                    throw;
                }
            }

            if (!template && path.LastSegment is ODL.NavigationPropertyLinkSegment)
            {
                IEdmCollectionType lastSegmentEdmType = path.LastSegment.EdmType as IEdmCollectionType;

                if (lastSegmentEdmType != null)
                {
                    ODL.EntityIdSegment entityIdSegment = null;
                    bool exceptionThrown = false;

                    try
                    {
                        entityIdSegment = uriParser.ParseEntityId();

                        if (entityIdSegment != null)
                        {
                            // Create another ODataUriParser to parse $id, which is absolute or relative.
                            ODL.ODataUriParser parser = new ODL.ODataUriParser(model, serviceRootUri, entityIdSegment.Id);
                            id = parser.ParsePath().LastSegment as ODL.KeySegment;
                        }
                    }
                    catch (ODataException)
                    {
                        // Exception was thrown while parsing the $id.
                        // We will throw another exception about the invalid $id.
                        exceptionThrown = true;
                    }

                    if (exceptionThrown ||
                        (entityIdSegment != null &&
                         (id == null ||
                          !(id.EdmType.IsOrInheritsFrom(lastSegmentEdmType.ElementType.Definition) ||
                            lastSegmentEdmType.ElementType.Definition.IsOrInheritsFrom(id.EdmType)))))
                    {
                        throw new ODataException(Error.Format(SRResources.InvalidDollarId, "$id" /*queryString.Get("$id")*/));
                    }
                }
            }

            // do validation for the odata path
            path.WalkWith(new DefaultODataPathValidator(model));

            // do segment translator (for example parameter alias, key & function parameter template, etc)
            var segments =
                ODataPathSegmentTranslator.Translate(model, path, uriParser.ParameterAliasNodes).ToList();

            if (unresolvedPathSegment != null)
            {
                segments.Add(unresolvedPathSegment);
            }

            if (!template)
            {
                AppendIdForRef(segments, id);
            }

            return(new ODataPath(segments)
            {
                ODLPath = path
            });
        }
 /// <summary>
 /// Computes the <see cref="IEdmNavigationSource"/> of the resource identified by this <see cref="ODataPath"/>.
 /// </summary>
 /// <param name="path">Path to compute the set for.</param>
 /// <returns>The <see cref="IEdmNavigationSource"/> of the resource, or null if the path does not identify a
 /// resource that is part of a set.</returns>
 public static IEdmNavigationSource NavigationSource(this ODataPath path)
 {
     return(path.LastSegment.TranslateWith(new DetermineNavigationSourceTranslator()));
 }
 /// <summary>
 /// Computes whether or not the resource identified by this <see cref="ODataPath"/> is a collection.
 /// </summary>
 /// <param name="path">Path to perform the computation on.</param>
 /// <returns>True if the resource if a resource set or collection of primitive or complex types. False otherwise.</returns>
 public static bool IsCollection(this ODataPath path)
 {
     return(path.LastSegment.TranslateWith(new IsCollectionTranslator()));
 }
 /// <summary>
 /// Get the string representation of <see cref="ODataPath"/>.
 /// mainly translate Query Url path.
 /// </summary>
 /// <param name="path">Path to perform the computation on.</param>
 /// <param name="urlKeyDelimiter">Mark whether key is segment</param>
 /// <returns>The string representation of the Query Url path.</returns>
 public static string ToResourcePathString(this ODataPath path, ODataUrlKeyDelimiter urlKeyDelimiter)
 {
     return(string.Concat(path.WalkWith(new PathSegmentToResourcePathTranslator(urlKeyDelimiter)).ToArray()).TrimStart('/'));
 }
 /// <summary>
 /// Computes the <see cref="IEdmTypeReference"/> of the resource identified by this <see cref="ODataPath"/>.
 /// </summary>
 /// <param name="path">Path to compute the type for.</param>
 /// <returns>The <see cref="IEdmTypeReference"/> of the resource, or null if the path does not identify a
 /// resource with a type.</returns>
 public static IEdmTypeReference EdmType(this ODataPath path)
 {
     return(path.LastSegment.EdmType.ToTypeReference());
 }
        /// <summary>
        /// Computes whether or not the ODataPath targets at an unknown segment.
        /// </summary>
        /// <param name="path">Path to perform the computation on.</param>
        /// <returns>True if the the ODataPath targets at an unknown segment. False otherwise.</returns>
        public static bool IsUndeclared(this ODataPath path)
        {
            ODataPathSegment lastNonTypeCastSegment = path.TrimEndingTypeSegment().LastSegment;

            return(lastNonTypeCastSegment is DynamicPathSegment);
        }
        /// <summary>
        /// Get the string representation of <see cref="ODataPath"/>.
        /// mainly translate Context Url path.
        /// </summary>
        /// <param name="path">Path to perform the computation on.</param>
        /// <returns>The string representation of the Context Url path.</returns>
        public static string ToContextUrlPathString(this ODataPath path)
        {
            StringBuilder pathString = new StringBuilder();
            PathSegmentToContextUrlPathTranslator pathTranslator = PathSegmentToContextUrlPathTranslator.DefaultInstance;
            ODataPathSegment priorSegment = null;
            bool             foundOperationWithoutPath = false;

            foreach (ODataPathSegment segment in path)
            {
                OperationSegment       operationSegment       = segment as OperationSegment;
                OperationImportSegment operationImportSegment = segment as OperationImportSegment;
                if (operationImportSegment != null)
                {
                    IEdmOperationImport operationImport = operationImportSegment.OperationImports.FirstOrDefault();
                    Debug.Assert(operationImport != null);

                    EdmPathExpression pathExpression = operationImport.EntitySet as EdmPathExpression;
                    if (pathExpression != null)
                    {
                        Debug.Assert(priorSegment == null); // operation import is always the first segment?
                        pathString.Append(pathExpression.Path);
                    }
                    else
                    {
                        pathString = operationImport.Operation.ReturnType != null ?
                                     new StringBuilder(operationImport.Operation.ReturnType.FullName()) :
                                     new StringBuilder("Edm.Untyped");

                        foundOperationWithoutPath = true;
                    }
                }
                else if (operationSegment != null)
                {
                    IEdmOperation operation = operationSegment.Operations.FirstOrDefault();
                    Debug.Assert(operation != null);

                    if (operation.IsBound &&
                        priorSegment != null &&
                        operation.Parameters.First().Type.Definition == priorSegment.EdmType)
                    {
                        if (operation.EntitySetPath != null)
                        {
                            foreach (string pathSegment in operation.EntitySetPath.PathSegments.Skip(1))
                            {
                                pathString.Append('/');
                                pathString.Append(pathSegment);
                            }
                        }
                        else if (operationSegment.EntitySet != null)
                        {
                            // Is it correct to check EntitySet?
                            pathString = new StringBuilder(operationSegment.EntitySet.Name);
                        }
                        else
                        {
                            pathString = operation.ReturnType != null ?
                                         new StringBuilder(operation.ReturnType.FullName()) :
                                         new StringBuilder("Edm.Untyped");

                            foundOperationWithoutPath = true;
                        }
                    }
                }
                else
                {
                    if (foundOperationWithoutPath)
                    {
                        pathString = new StringBuilder(segment.EdmType.FullTypeName());
                        foundOperationWithoutPath = false;
                    }
                    else
                    {
                        pathString.Append(segment.TranslateWith(pathTranslator));
                    }
                }

                priorSegment = segment;
            }

            return(pathString.ToString().TrimStart('/'));
        }
Example #10
0
 /// <summary>
 /// Constructor for ODataQueryOptionParser
 /// </summary>
 /// <param name="model">Model to use for metadata binding.</param>
 /// <param name="odataPath">The odata path to apply the query option on.</param>
 /// <param name="queryOptions">The dictionary storing query option key-value pairs.</param>
 public ODataQueryOptionParser(IEdmModel model, ODataPath odataPath, IDictionary <string, string> queryOptions)
     : this(model, odataPath, queryOptions, null)
 {
 }
        /// <summary>
        /// Computes whether or not the ODataPath targets at an individual property.
        /// </summary>
        /// <param name="path">Path to perform the computation on.</param>
        /// <returns>True if the the ODataPath targets at an individual property. False otherwise.</returns>
        public static bool IsIndividualProperty(this ODataPath path)
        {
            ODataPathSegment lastNonTypeCastSegment = path.TrimEndingTypeSegment().LastSegment;

            return(lastNonTypeCastSegment is PropertySegment || lastNonTypeCastSegment is DynamicPathSegment);
        }
        /// <summary>
        /// Build a segment representing a property.
        /// </summary>
        /// <param name="path">Path to perform the computation on.</param>
        /// <param name="property">The property this segment represents.</param>
        /// <returns>>A new ODataPath with property segment appended to the end.</returns>
        public static ODataPath AddPropertySegment(this ODataPath path, IEdmStructuralProperty property)
        {
            PropertySegment propertySegment = new PropertySegment(property);

            return(path.AddSegment(propertySegment));
        }
        /// <summary>
        /// Build a segment representing a navigation property.
        /// </summary>
        /// <param name="path">Path to perform the computation on.</param>
        /// <param name="navigationProperty">The navigation property this segment represents.</param>
        /// <param name="navigationSource">The navigation source of the entities targeted by this navigation property. This can be null.</param>
        /// <returns>A new ODataPath with navigation property segment appended to the end.</returns>
        public static ODataPath AddNavigationPropertySegment(this ODataPath path, IEdmNavigationProperty navigationProperty, IEdmNavigationSource navigationSource)
        {
            NavigationPropertySegment navigationSegment = new NavigationPropertySegment(navigationProperty, navigationSource);

            return(path.AddSegment(navigationSegment));
        }
 private static void AppendLastSegment(SplitEndingSegmentOfTypeHandler <TypeSegment> handler, ODataPath newPath)
 {
     newPath.AddRange(handler.LastPart);
 }
Example #15
0
        public override ODataPath Parse(string serviceRoot, string odataPath, IServiceProvider requestContainer)
        {
            ODL.ODataUriParser uriParser;
            Uri       serviceRootUri = null;
            Uri       fullUri        = null;
            string    dataSourceName = odataPath.Split('/')[0];
            IEdmModel model          = requestContainer.GetService(typeof(IEdmModel)) as IEdmModel;

            Contract.Assert(serviceRoot != null);

            serviceRootUri = new Uri(
                serviceRoot.EndsWith("/", StringComparison.Ordinal)
                    ? serviceRoot
                    : serviceRoot + "/");


            // Concatenate the root and path and create a Uri. Using Uri to build a Uri from
            // a root and relative path changes the casing on .NetCore. However, odataPath may
            // be a full Uri.
            if (!Uri.TryCreate(odataPath, UriKind.Absolute, out fullUri))
            {
                fullUri = new Uri(serviceRootUri + odataPath);
            }
            serviceRootUri = new Uri(serviceRootUri, dataSourceName);
            uriParser      = new ODL.ODataUriParser(model, serviceRootUri, fullUri, requestContainer);

            if (UrlKeyDelimiter != null)
            {
                uriParser.UrlKeyDelimiter = UrlKeyDelimiter;
            }
            else
            {
                // ODL changes to use ODataUrlKeyDelimiter.Slash as default value.
                // Web API still uses the ODataUrlKeyDelimiter.Parentheses as default value.
                // Please remove it after fix: https://github.com/OData/odata.net/issues/642
                uriParser.UrlKeyDelimiter = ODataUrlKeyDelimiter.Parentheses;
            }

            ODL.ODataPath         path;
            UnresolvedPathSegment unresolvedPathSegment = null;

            ODL.KeySegment id = null;

            try
            {
                path = uriParser.ParsePath();
            }
            catch (ODL.ODataUnrecognizedPathException ex)
            {
                if (ex.ParsedSegments != null &&
                    ex.ParsedSegments.Any() &&
                    (ex.ParsedSegments.Last().EdmType is IEdmComplexType ||
                     ex.ParsedSegments.Last().EdmType is IEdmEntityType) &&
                    ex.CurrentSegment != ODataSegmentKinds.Count)
                {
                    if (!ex.UnparsedSegments.Any())
                    {
                        path = new ODL.ODataPath(ex.ParsedSegments);
                        unresolvedPathSegment = new UnresolvedPathSegment(ex.CurrentSegment);
                    }
                    else
                    {
                        // Throw ODataException if there is some segment following the unresolved segment.
                        throw new ODataException(String.Format(CultureInfo.CurrentCulture,
                                                               "InvalidPathSegment",
                                                               ex.UnparsedSegments.First(),
                                                               ex.CurrentSegment));
                    }
                }
                else
                {
                    throw;
                }
            }
            if (path.LastSegment is ODL.NavigationPropertyLinkSegment)
            {
                IEdmCollectionType lastSegmentEdmType = path.LastSegment.EdmType as IEdmCollectionType;

                if (lastSegmentEdmType != null)
                {
                    ODL.EntityIdSegment entityIdSegment = null;
                    bool exceptionThrown = false;

                    try
                    {
                        entityIdSegment = uriParser.ParseEntityId();

                        if (entityIdSegment != null)
                        {
                            // Create another ODataUriParser to parse $id, which is absolute or relative.
                            ODL.ODataUriParser parser = new ODL.ODataUriParser(model, serviceRootUri, entityIdSegment.Id, requestContainer);
                            id = parser.ParsePath().LastSegment as ODL.KeySegment;
                        }
                    }
                    catch (ODataException)
                    {
                        // Exception was thrown while parsing the $id.
                        // We will throw another exception about the invalid $id.
                        exceptionThrown = true;
                    }

                    if (exceptionThrown ||
                        (entityIdSegment != null &&
                         (id == null ||
                          !(id.EdmType.IsOrInheritsFrom(lastSegmentEdmType.ElementType.Definition) ||
                            lastSegmentEdmType.ElementType.Definition.IsOrInheritsFrom(id.EdmType)))))
                    {
                        // System.Net.Http on NetCore does not have the Uri extension method
                        // ParseQueryString(), to avoid a platform-specific call, extract $id manually.
                        string idValue = fullUri.Query;
                        string idParam = "$id=";
                        int    start   = idValue.IndexOf(idParam, StringComparison.OrdinalIgnoreCase);
                        if (start >= 0)
                        {
                            int end = idValue.IndexOf("&", start, StringComparison.OrdinalIgnoreCase);
                            if (end >= 0)
                            {
                                idValue = idValue.Substring(start + idParam.Length, end - 1);
                            }
                            else
                            {
                                idValue = idValue.Substring(start + idParam.Length);
                            }
                        }

                        throw new ODataException(String.Format(CultureInfo.CurrentCulture, "InvalidDollarId", idValue));
                    }
                }
            }

            // do validation for the odata path
            path.WalkWith(new DefaultODataPathValidator(model));

            // do segment translator (for example parameter alias, key & function parameter template, etc)
            var segments =
                ODataPathSegmentTranslator.Translate(model, path, uriParser.ParameterAliasNodes).ToList();

            if (unresolvedPathSegment != null)
            {
                segments.Add(unresolvedPathSegment);
            }
            AppendIdForRef(segments, id);
            return(new ODataPath(segments));
        }
Example #16
0
 /// <summary>
 /// Adds a range of segments to the current path
 /// </summary>
 /// <param name="oDataPath"></param>
 internal void AddRange(ODataPath oDataPath)
 {
     this.segments.AddRange(oDataPath.segments);
 }