public RoutePattern Build() { var parameters = new List <RoutePatternParameter>(); for (var i = 0; i < PathSegments.Count; i++) { var segment = PathSegments[i]; for (var j = 0; j < segment.Parts.Count; j++) { if (segment.Parts[j] is RoutePatternParameter parameter) { parameters.Add(parameter); } } } return(new RoutePattern(RawText, parameters.ToArray(), PathSegments.ToArray())); }
/// <summary> /// Execute the query represented by an OData URI against an <c>IQueryable</c> data source /// </summary> /// <param name="query"><c>IQueryable</c> data source</param> /// <param name="inputType">Model data type</param> /// <param name="dynamicAccessor">Expression for accessing fields on dynamic model objects</param> public ODataQueryable <object> Execute(IQueryable query, ExecutionSettings settings = null) { if (query == null) { throw new ArgumentNullException("query", "Query cannot be null"); } settings = settings ?? ExecutionSettings.Empty; var queryResult = query; var constrainedQuery = query; var path = settings.GetEdmSource(this); var inputType = settings.GetInputType(query); var dynamicAccessor = settings.GetDynamicAccessor(); var lookupByKey = false; var children = this.QueryOption.Where(n => !(n is IgnoredNode) && !(n is AliasNode)).ToList(); // Try and do an ID lookup if applicable var segments = PathSegments.ToArray(); var functionNode = segments.FirstOrDefault() as CallNode; if (functionNode != null && segments.Length == 1) { var entity = ((IEdmCollectionType)path.Type).ElementType.ToStructuredType() as IEdmEntityType; if (entity != null && entity.Key().Count() == functionNode.Arguments.Count) { var keys = entity.Key().ToArray(); var root = default(ODataNode); for (var i = 0; i < keys.Length; i++) { var newNode = ODataNode.Equals(ODataNode.Identifier(keys[i].Name), functionNode.Arguments[i]); if (root == null) { root = newNode; } else { newNode = ODataNode.And(root, newNode); } } children.RemoveByFilter(n => n is FilterNode); children.Add(ODataNode.Filter(root)); lookupByKey = true; } } var maxPageSize = settings.GetMaxPageSize(); if (maxPageSize.HasValue && (!QueryOption.Top.HasValue || maxPageSize.Value < QueryOption.Top.Value)) { children.RemoveByFilter(n => n is TopNode); children.Add(ODataNode.Top(ODataNode.Literal(maxPageSize.Value))); } children.Sort(); // These should always come first foreach (var node in children.Where(o => !(o is SelectNode))) { BuildQuery(node, inputType, dynamicAccessor, ref queryResult, ref constrainedQuery); } var selectNode = children.FirstOrDefault(o => o is SelectNode); if (selectNode != null) { constrainedQuery = ProjectQuery(constrainedQuery, selectNode, inputType, dynamicAccessor); } return(new ODataQueryable <object>(constrainedQuery, this) { LookupByKey = lookupByKey }); }