private QueryExpression BuildQueryFromSegments() { var segments = this.currentUri.Segments; EntitySet currentEntitySet = null; QueryExpression query = null; foreach (var segment in segments) { if (segment.SegmentType == ODataUriSegmentType.ServiceRoot || segment == SystemSegment.Count || segment == SystemSegment.EntityReferenceLinks || segment == SystemSegment.Value) { continue; } else if (segment.SegmentType == ODataUriSegmentType.EntitySet) { // must be the root query ExceptionUtilities.Assert(query == null, "Cannot have multiple entity set segments in the uri"); var entitySetSegment = (EntitySetSegment)segment; query = CommonQueryBuilder.Root(entitySetSegment.EntitySet.Name, this.Repository.RootDataTypes[entitySetSegment.EntitySet.Name].CreateCollectionType()); currentEntitySet = entitySetSegment.EntitySet; } else if (segment.SegmentType == ODataUriSegmentType.Key) { // build the key expression ExceptionUtilities.CheckObjectNotNull(query, "Key expression present in uri before any root segment"); var keySegment = (KeyExpressionSegment)segment; var values = keySegment.IncludedValues.Select(p => new NamedValue(p.Key.Name, p.Value)); query = query.Key(values); this.shouldLastSegmentBeSingleton = true; } else if (segment.SegmentType == ODataUriSegmentType.NavigationProperty) { ExceptionUtilities.CheckObjectNotNull(query, "Navigation property present in uri before any root segment"); var navigationSegment = (NavigationSegment)segment; query = query.Property(navigationSegment.NavigationProperty.Name); ExceptionUtilities.CheckObjectNotNull(currentEntitySet, "Expected an EntitySet Segment prior to a NavigationSegment"); currentEntitySet = currentEntitySet.GetRelatedEntitySet(navigationSegment.NavigationProperty); this.shouldLastSegmentBeSingleton = false; } else if (segment.SegmentType == ODataUriSegmentType.NamedStream) { var namedStreamSegment = (NamedStreamSegment)segment; query = query.Property(namedStreamSegment.Name); this.shouldLastSegmentBeSingleton = false; } else if (segment.SegmentType == ODataUriSegmentType.EntityType) { query = this.AddEntityTypeFilter(currentEntitySet, query, (EntityTypeSegment)segment); } else if (segment.SegmentType == ODataUriSegmentType.Function) { ExceptionUtilities.Assert(query == null, "Cannot have multiple root query segments in the uri"); var serviceOperationSegment = (FunctionSegment)segment; Function serviceOperation = serviceOperationSegment.Function; var bodyAnnotation = serviceOperation.Annotations.OfType <FunctionBodyAnnotation>().SingleOrDefault(); ExceptionUtilities.CheckObjectNotNull(bodyAnnotation, "Cannot evaluate function without body annotation"); List <QueryExpression> serviceOpArguments = new List <QueryExpression>(); foreach (var parameter in serviceOperation.Parameters) { var parameterPrimitiveType = parameter.DataType as PrimitiveDataType; ExceptionUtilities.CheckObjectNotNull(parameterPrimitiveType, "Non primitive parameter types are unsupported"); string parameterValue; if (this.currentUri.CustomQueryOptions.TryGetValue(parameter.Name, out parameterValue)) { object argValue = this.LiteralConverter.DeserializePrimitive(parameterValue, parameterPrimitiveType.GetFacetValue <PrimitiveClrTypeFacet, Type>(typeof(object))); serviceOpArguments.Add(CommonQueryBuilder.Constant(argValue)); } else { serviceOpArguments.Add(CommonQueryBuilder.Null(this.Repository.TypeLibrary.GetDefaultQueryType(parameterPrimitiveType))); } } query = new QueryCustomFunctionCallExpression( this.Repository.TypeLibrary.GetDefaultQueryType(serviceOperation.ReturnType), serviceOperation, bodyAnnotation.FunctionBody, false, false, serviceOpArguments.ToArray()); serviceOperation.TryGetExpectedServiceOperationEntitySet(out currentEntitySet); } else { // must be a property segment var propertySegment = segment as PropertySegment; ExceptionUtilities.CheckObjectNotNull(propertySegment, "Uri segments contained unhandled segment type '{0}'", segment.SegmentType); ExceptionUtilities.CheckObjectNotNull(query, "Property present in uri before any root segment"); query = query.Property(propertySegment.Property.Name); this.shouldLastSegmentBeSingleton = false; } } return(query); }