/// <inheritdoc />
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.Function)
            {
                BoundFunctionPathSegment functionSegment = (BoundFunctionPathSegment)pathSegment;
                if (FunctionName == functionSegment.FunctionName)
                {
                    var enumNames = functionSegment.Function.Parameters.Where(p => p.Type.IsEnum()).Select(p => p.Name);
                    if (KeyValuePathSegmentTemplate.TryMatch(ParameterMappings, functionSegment.Values, values,
                        enumNames))
                    {
                        foreach (KeyValuePair<string, string> nameAndValue in functionSegment.Values)
                        {
                            string name = nameAndValue.Key;
                            object value = functionSegment.GetParameterValue(name);

                            ProcedureRoutingConventionHelpers.AddFunctionParameters(functionSegment.Function, name,
                                value, values, values, ParameterMappings);
                        }

                        return true;
                    }
                }
            }

            return false;
        }
        private static void ValidateCount(ODataPathSegment segment, IEdmModel model)
        {
            Contract.Assert(segment != null);
            Contract.Assert(model != null);

            NavigationPathSegment navigationPathSegment = segment as NavigationPathSegment;
            if (navigationPathSegment != null)
            {
                if (EdmLibHelpers.IsNotCountable(navigationPathSegment.NavigationProperty, model))
                {
                    throw new InvalidOperationException(Error.Format(
                        SRResources.NotCountablePropertyUsedForCount,
                        navigationPathSegment.NavigationPropertyName));
                }
                return;
            }

            PropertyAccessPathSegment propertyAccessPathSegment = segment as PropertyAccessPathSegment;
            if (propertyAccessPathSegment != null)
            {
                if (EdmLibHelpers.IsNotCountable(propertyAccessPathSegment.Property, model))
                {
                    throw new InvalidOperationException(Error.Format(
                        SRResources.NotCountablePropertyUsedForCount,
                        propertyAccessPathSegment.PropertyName));
                }
            }
        }
        /// <inheritdoc />
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.DynamicProperty)
            {
                var dynamicPropertyPathSegment = (DynamicPropertyPathSegment)pathSegment;

                // If we're treating the property name as a parameter store the provided name in our values collection
                // using the name from the template as the key.
                if (TreatPropertyNameAsParameterName)
                {
                    values[PropertyName] = dynamicPropertyPathSegment.PropertyName;
                    values[ODataParameterValue.ParameterValuePrefix + PropertyName] =
                        new ODataParameterValue(dynamicPropertyPathSegment.PropertyName,
                            EdmLibHelpers.GetEdmPrimitiveTypeReferenceOrNull(typeof(string)));
                    return true;
                }

                if (PropertyName == dynamicPropertyPathSegment.PropertyName)
                {
                    return true;
                }
            }

            return false;
        }
        /// <inheritdoc />
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.Key)
            {
                KeyValuePathSegment keySegment = (KeyValuePathSegment)pathSegment;
                return TryMatch(ParameterMappings, keySegment.Values, values, null);
            }

            return false;
        }
        /// <inheritdoc />
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.Function)
            {
                BoundFunctionPathSegment functionSegment = (BoundFunctionPathSegment)pathSegment;
                if (FunctionName == functionSegment.FunctionName)
                {
                    return KeyValuePathSegmentTemplate.TryMatch(ParameterMappings, functionSegment.Values, values);
                }
            }

            return false;
        }
        /// <inheritdoc />
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.UnboundFunction)
            {
                UnboundFunctionPathSegment functionSegment = (UnboundFunctionPathSegment)pathSegment;
                if (_functionName == functionSegment.FunctionName)
                {
                    var enumNames = functionSegment.Function.Function.Parameters.Where(p => p.Type.IsEnum()).Select(p => p.Name);
                    return KeyValuePathSegmentTemplate.TryMatch(ParameterMappings, functionSegment.Values, values, enumNames);
                }
            }

            return false;
        }
 private void HandleCountPathSegment(ODataPathSegment segment)
 {
     this.IsCountPathSegmentPresent = true;
 }
 private void HandleValuePathSegment(ODataPathSegment segment)
 {
     this.IsValuePathSegmentPresent = true;
 }
 private void HandleSingletonPathSegment(ODataPathSegment segment)
 {
     var singletonPathSegment = (SingletonPathSegment)segment;
     var singleton = singletonPathSegment.Singleton;
     this.currentEntityType = singleton.EntityType();
     this.queryable = this.api.Source(singleton.Name, (object[])null);
     this.currentType = this.queryable.ElementType;
 }
Beispiel #10
0
        private void HandleUnboundFunctionPathSegment(ODataPathSegment segment)
        {
            var unboundFunctionPathSegment = (UnboundFunctionPathSegment)segment;
            var functionImport = unboundFunctionPathSegment.Function;
            var entityTypeRef = functionImport.Function.ReturnType.AsEntity();
            this.currentEntityType = entityTypeRef == null ? null : entityTypeRef.EntityDefinition();

            object[] queryArgs = null;
            if (functionImport.Function.Parameters.Any())
            {
                queryArgs = functionImport.Function.Parameters.Select(
                    p => unboundFunctionPathSegment.GetParameterValue(p.Name)).ToArray();
            }

            this.queryable = this.api.Source(functionImport.Name, queryArgs);
            this.currentType = queryable.ElementType;
        }
Beispiel #11
0
 /// <inheritdoc/>
 public override bool TryMatch(ODataPathSegment pathSegment, IDictionary <string, object> values)
 {
     return(pathSegment.SegmentKind == ODataSegmentKinds.Batch);
 }
        private void HandleNavigationPathSegment(ODataPathSegment segment)
        {
            var navigationSegment = (NavigationPathSegment)segment;
            var entityParameterExpression = Expression.Parameter(this.currentType);
            var navigationPropertyExpression =
                Expression.Property(entityParameterExpression, navigationSegment.NavigationPropertyName);

            this.currentEntityType = navigationSegment.NavigationProperty.ToEntityType();

            if (navigationSegment.NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                // get the element type of the target
                // (the type should be an EntityCollection<T> for navigation queries).
                this.currentType = navigationPropertyExpression.Type.GetEnumerableItemType();

                // need to explicitly define the delegate type as IEnumerable<T>
                Type delegateType = typeof(Func<,>).MakeGenericType(
                    queryable.ElementType,
                    typeof(IEnumerable<>).MakeGenericType(this.currentType));
                LambdaExpression selectBody =
                    Expression.Lambda(delegateType, navigationPropertyExpression, entityParameterExpression);

                this.queryable = ExpressionHelpers.SelectMany(this.queryable, selectBody, this.currentType);
            }
            else
            {
                this.currentType = navigationPropertyExpression.Type;
                LambdaExpression selectBody =
                    Expression.Lambda(navigationPropertyExpression, entityParameterExpression);
                this.queryable = ExpressionHelpers.Select(this.queryable, selectBody);
            }
        }
 /// <inheritdoc/>
 public override bool TryMatch(ODataPathSegment pathSegment, IDictionary <string, object> values)
 {
     return(false);
 }
Beispiel #14
0
        private void HandlePropertyAccessPathSegment(ODataPathSegment segment)
        {
            var propertySegment = (PropertyAccessPathSegment)segment;
            var entityParameterExpression = Expression.Parameter(this.currentType);
            var structuralPropertyExpression =
                Expression.Property(entityParameterExpression, propertySegment.PropertyName);

            // Check whether property is null or not before futher selection
            if (propertySegment.Property.Type.IsNullable)
            {
                var whereExpression =
                    CreateNotEqualsNullExpression(structuralPropertyExpression, entityParameterExpression);
                this.queryable = ExpressionHelpers.Where(this.queryable, whereExpression, this.currentType);
            }

            if (propertySegment.Property.Type.IsCollection())
            {
                // Produces new query like 'queryable.SelectMany(param => param.PropertyName)'.
                // Suppose 'param.PropertyName' is of type 'IEnumerable<T>', the type of the
                // resulting query would be 'IEnumerable<T>' too.
                this.currentType = structuralPropertyExpression.Type.GetEnumerableItemType();
                var delegateType = typeof(Func<,>).MakeGenericType(
                    this.queryable.ElementType,
                    typeof(IEnumerable<>).MakeGenericType(this.currentType));
                var selectBody =
                    Expression.Lambda(delegateType, structuralPropertyExpression, entityParameterExpression);
                this.queryable = ExpressionHelpers.SelectMany(this.queryable, selectBody, this.currentType);
            }
            else
            {
                // Produces new query like 'queryable.Select(param => param.PropertyName)'.
                this.currentType = structuralPropertyExpression.Type;
                LambdaExpression selectBody =
                    Expression.Lambda(structuralPropertyExpression, entityParameterExpression);
                this.queryable = ExpressionHelpers.Select(this.queryable, selectBody);
            }
        }
        /// <summary>
        /// Parses the next OData path segment following a complex-typed segment.
        /// </summary>
        /// <param name="model">The model to use for path parsing.</param>
        /// <param name="previous">The previous path segment.</param>
        /// <param name="previousEdmType">The EDM type of the OData path up to the previous segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <param name="segments">The queue of pending segments.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseAtComplex(IEdmModel model, ODataPathSegment previous,
            IEdmType previousEdmType, string segment, Queue<string> segments)
        {
            if (previous == null)
            {
                throw Error.ArgumentNull("previous");
            }
            if (segments == null)
            {
                throw Error.ArgumentNull("segments");
            }
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }

            IEdmComplexType previousType = previousEdmType as IEdmComplexType;
            if (previousType == null)
            {
                throw Error.Argument(SRResources.PreviousSegmentMustBeComplexType, previousEdmType);
            }

            // look for properties
            IEdmProperty property = previousType.Properties().SingleOrDefault(p => p.Name == segment);
            if (property != null)
            {
                return new PropertyAccessPathSegment(property);
            }

            // Treating as an open property
            return new UnresolvedPathSegment(segment);
        }
        /// <inheritdoc/>
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.Singleton)
            {
                SingletonPathSegment singletonSegment = (SingletonPathSegment)pathSegment;
                return singletonSegment.Singleton == Singleton && singletonSegment.SingletonName == SingletonName;
            }

            return false;
        }
        /// <summary>
        /// Parses the next OData path segment following a collection.
        /// </summary>
        /// <param name="model">The model to use for path parsing.</param>
        /// <param name="previous">The previous path segment.</param>
        /// <param name="previousEdmType">The EDM type of the OData path up to the previous segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <param name="segments">The queue of pending segments.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseAtCollection(IEdmModel model, ODataPathSegment previous,
            IEdmType previousEdmType, string segment, Queue<string> segments)
        {
            if (previous == null)
            {
                throw Error.ArgumentNull("previous");
            }
            if (segments == null)
            {
                throw Error.ArgumentNull("segments");
            }
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }

            if (previousEdmType == null)
            {
                throw Error.InvalidOperation(SRResources.PreviousSegmentEdmTypeCannotBeNull);
            }

            IEdmCollectionType collection = previousEdmType as IEdmCollectionType;
            if (collection == null)
            {
                throw Error.Argument(SRResources.PreviousSegmentMustBeCollectionType, previousEdmType);
            }

            switch (collection.ElementType.Definition.TypeKind)
            {
                case EdmTypeKind.Entity:
                    return ParseAtEntityCollection(model, previous, previousEdmType, segment, segments);

                default:
                    throw new ODataException(Error.Format(SRResources.InvalidPathSegment, segment, previous));
            }
        }
        /// <summary>
        /// Parses the next OData path segment.
        /// </summary>
        /// <param name="model">The model to use for path parsing.</param>
        /// <param name="previous">The previous path segment.</param>
        /// <param name="previousEdmType">The EDM type of the OData path up to the previous segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <param name="segments">The queue of pending segments.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseNextSegment(IEdmModel model, ODataPathSegment previous,
            IEdmType previousEdmType, string segment, Queue<string> segments)
        {
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }

            if (previous == null)
            {
                // Parse entry node
                return ParseEntrySegment(model, segment, segments);
            }
            else
            {
                // Parse non-entry node
                if (previousEdmType == null)
                {
                    throw new ODataException(Error.Format(SRResources.InvalidPathSegment, segment, previous));
                }

                switch (previousEdmType.TypeKind)
                {
                    case EdmTypeKind.Collection:
                        return ParseAtCollection(model, previous, previousEdmType, segment, segments);

                    case EdmTypeKind.Entity:
                        return ParseAtEntity(model, previous, previousEdmType, segment, segments);

                    case EdmTypeKind.Complex:
                        return ParseAtComplex(model, previous, previousEdmType, segment, segments);

                    case EdmTypeKind.Primitive:
                        return ParseAtPrimitiveProperty(model, previous, previousEdmType, segment, segments);

                    case EdmTypeKind.Enum:
                        return ParseAtEnumProperty(model, previous, previousEdmType, segment, segments);

                    default:
                        throw new ODataException(Error.Format(SRResources.InvalidPathSegment, segment, previous));
                }
            }
        }
        /// <inheritdoc/>
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.ComplexCast)
            {
                ComplexCastPathSegment castSegment = (ComplexCastPathSegment)pathSegment;
                return castSegment.CastType == CastType && castSegment.CastTypeName == CastTypeName;
            }

            return false;
        }
Beispiel #20
0
        private void HandleKeyValuePathSegment(ODataPathSegment segment)
        {
            var keySegment = (KeyValuePathSegment)segment;

            var parameterExpression = Expression.Parameter(this.currentType, DefaultNameOfParameterExpression);
            var keyValues = GetPathKeyValues(keySegment, this.currentEntityType);

            BinaryExpression keyFilter = null;
            foreach (KeyValuePair<string, object> keyValuePair in keyValues)
            {
                var equalsExpression =
                    CreateEqualsExpression(parameterExpression, keyValuePair.Key, keyValuePair.Value);
                keyFilter = keyFilter == null ? equalsExpression : Expression.And(keyFilter, equalsExpression);
            }

            var whereExpression = Expression.Lambda(keyFilter, parameterExpression);
            this.queryable = ExpressionHelpers.Where(this.queryable, whereExpression, this.currentType);
        }
        /// <inheritdoc/>
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.Navigation)
            {
                NavigationPathSegment navigationSegment = (NavigationPathSegment)pathSegment;
                return navigationSegment.NavigationProperty == NavigationProperty
                    && navigationSegment.NavigationPropertyName == NavigationPropertyName;
            }

            return false;
        }
Beispiel #22
0
        private void HandleNavigationPathSegment(ODataPathSegment segment)
        {
            var navigationSegment = (NavigationPathSegment)segment;
            var entityParameterExpression = Expression.Parameter(this.currentType);
            var navigationPropertyExpression =
                Expression.Property(entityParameterExpression, navigationSegment.NavigationPropertyName);

            this.currentEntityType = navigationSegment.NavigationProperty.ToEntityType();

            // TODO GitHubIssue#330: EF QueryExecutor will throw exception if check whether collections is null added.
            // Error message likes "Cannot compare elements of type 'ICollection`1[[EntityType]]'.
            // Only primitive types, enumeration types and entity types are supported."
            if (navigationSegment.NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                // get the element type of the target
                // (the type should be an EntityCollection<T> for navigation queries).
                this.currentType = navigationPropertyExpression.Type.GetEnumerableItemType();

                // need to explicitly define the delegate type as IEnumerable<T>
                Type delegateType = typeof(Func<,>).MakeGenericType(
                    queryable.ElementType,
                    typeof(IEnumerable<>).MakeGenericType(this.currentType));
                LambdaExpression selectBody =
                    Expression.Lambda(delegateType, navigationPropertyExpression, entityParameterExpression);

                this.queryable = ExpressionHelpers.SelectMany(this.queryable, selectBody, this.currentType);
            }
            else
            {
                // Check whether property is null or not before futher selection
                var whereExpression =
                    CreateNotEqualsNullExpression(navigationPropertyExpression, entityParameterExpression);
                this.queryable = ExpressionHelpers.Where(this.queryable, whereExpression, this.currentType);

                this.currentType = navigationPropertyExpression.Type;
                LambdaExpression selectBody =
                    Expression.Lambda(navigationPropertyExpression, entityParameterExpression);
                this.queryable = ExpressionHelpers.Select(this.queryable, selectBody);
            }
        }
        /// <inheritdoc/>
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.Action)
            {
                BoundActionPathSegment actionSegment = (BoundActionPathSegment)pathSegment;
                return actionSegment.Action == Action && actionSegment.ActionName == ActionName;
            }

            return false;
        }
        /// <summary>
        /// Parses the next OData path segment following an entity collection.
        /// </summary>
        /// <param name="model">The model to use for path parsing.</param>
        /// <param name="previous">The previous path segment.</param>
        /// <param name="previousEdmType">The EDM type of the OData path up to the previous segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <param name="segments">The queue of pending segments.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseAtEntityCollection(IEdmModel model, ODataPathSegment previous,
            IEdmType previousEdmType, string segment, Queue<string> segments)
        {
            if (previous == null)
            {
                throw Error.ArgumentNull("previous");
            }
            if (segments == null)
            {
                throw Error.ArgumentNull("segments");
            }
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }

            if (previousEdmType == null)
            {
                throw Error.InvalidOperation(SRResources.PreviousSegmentEdmTypeCannotBeNull);
            }
            IEdmCollectionType collectionType = previousEdmType as IEdmCollectionType;
            if (collectionType == null)
            {
                throw Error.Argument(SRResources.PreviousSegmentMustBeEntityCollectionType, previousEdmType);
            }
            IEdmEntityType elementType = collectionType.ElementType.Definition as IEdmEntityType;
            if (elementType == null)
            {
                throw Error.Argument(SRResources.PreviousSegmentMustBeEntityCollectionType, previousEdmType);
            }

            // look for keys first.
            if (segment.StartsWith("(", StringComparison.Ordinal) && segment.EndsWith(")", StringComparison.Ordinal))
            {
                Contract.Assert(segment.Length >= 2);
                string value = segment.Substring(1, segment.Length - 2);
                return new KeyValuePathSegment(value);
            }

            // next look for casts
            IEdmEntityType castType = model.FindDeclaredType(segment) as IEdmEntityType;
            if (castType != null)
            {
                IEdmType previousElementType = collectionType.ElementType.Definition;
                if (!castType.IsOrInheritsFrom(previousElementType) && !previousElementType.IsOrInheritsFrom(castType))
                {
                    throw new ODataException(Error.Format(SRResources.InvalidCastInPath, castType, previousElementType));
                }
                return new CastPathSegment(castType);
            }

            // look for $ref
            if (segment == ODataSegmentKinds.Ref)
            {
                return new RefPathSegment();
            }

            // now look for bindable actions
            IEdmAction action = model.FindAction(segment, collectionType);
            if (action != null)
            {
                return new BoundActionPathSegment(action);
            }

            // Try to match this to a function call
            BoundFunctionPathSegment pathSegment = TryMatchBoundFunctionCall(segment, segments, model, bindingType: collectionType);
            if (pathSegment != null)
            {
                return pathSegment;
            }

            throw new ODataException(Error.Format(SRResources.NoActionFoundForCollection, segment, collectionType.ElementType));
        }
        /// <inheritdoc/>
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.EntitySet)
            {
                EntitySetPathSegment entitySetSegment = (EntitySetPathSegment)pathSegment;
                return entitySetSegment.EntitySet == EntitySet && entitySetSegment.EntitySetName == EntitySetName;
            }

            return false;
        }
        /// <inheritdoc/>
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.Property)
            {
                PropertyAccessPathSegment propertySegment = (PropertyAccessPathSegment)pathSegment;
                return propertySegment.Property == Property && propertySegment.PropertyName == PropertyName;
            }

            return false;
        }
        /// <summary>
        /// Parses the next OData path segment following a primitive property.
        /// </summary>
        /// <param name="model">The model to use for path parsing.</param>
        /// <param name="previous">The previous path segment.</param>
        /// <param name="previousEdmType">The EDM type of the OData path up to the previous segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <param name="segments">The queue of pending segments.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseAtPrimitiveProperty(IEdmModel model, ODataPathSegment previous,
            IEdmType previousEdmType, string segment, Queue<string> segments)
        {
            if (previous == null)
            {
                throw Error.ArgumentNull("previous");
            }
            if (segments == null)
            {
                throw Error.ArgumentNull("segments");
            }
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }

            if (segment == ODataSegmentKinds.Value)
            {
                return new ValuePathSegment();
            }

            throw new ODataException(Error.Format(SRResources.InvalidPathSegment, segment, previous));
        }
        /// <inheritdoc />
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.UnboundFunction)
            {
                UnboundFunctionPathSegment functionSegment = (UnboundFunctionPathSegment)pathSegment;
                return functionSegment.Function == Function && functionSegment.FunctionName == FunctionName;
            }

            return false;
        }
        /// <summary>
        /// Parses the next OData path segment following an entity.
        /// </summary>
        /// <param name="model">The model to use for path parsing.</param>
        /// <param name="previous">The previous path segment.</param>
        /// <param name="previousEdmType">The EDM type of the OData path up to the previous segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <param name="segments">The queue of pending segments.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseAtEntity(IEdmModel model, ODataPathSegment previous,
            IEdmType previousEdmType, string segment, Queue<string> segments)
        {
            if (previous == null)
            {
                throw Error.ArgumentNull("previous");
            }
            if (segments == null)
            {
                throw Error.ArgumentNull("segments");
            }
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }
            IEdmEntityType previousType = previousEdmType as IEdmEntityType;
            if (previousType == null)
            {
                throw Error.Argument(SRResources.PreviousSegmentMustBeEntityType, previousEdmType);
            }

            // first look for navigation properties
            IEdmNavigationProperty navigation = previousType.NavigationProperties().SingleOrDefault(np => np.Name == segment);
            if (navigation != null)
            {
                return new NavigationPathSegment(navigation);
            }

            // next look for properties
            IEdmProperty property = previousType.Properties().SingleOrDefault(p => p.Name == segment);
            if (property != null)
            {
                return new PropertyAccessPathSegment(property);
            }

            // next look for type casts
            IEdmEntityType castType = model.FindDeclaredType(segment) as IEdmEntityType;
            if (castType != null)
            {
                if (!castType.IsOrInheritsFrom(previousType) && !previousType.IsOrInheritsFrom(castType))
                {
                    throw new ODataException(Error.Format(SRResources.InvalidCastInPath, castType, previousType));
                }
                return new CastPathSegment(castType);
            }

            // look for $ref
            if (segment == ODataSegmentKinds.Ref)
            {
                return new RefPathSegment();
            }

            // finally look for bindable procedures
            IEdmAction action = model.FindAction(segment, previousType);
            if (action != null)
            {
                return new BoundActionPathSegment(action);
            }

            // Try to match this to a function call
            BoundFunctionPathSegment pathSegment = TryMatchBoundFunctionCall(segment, segments, model, bindingType: previousType);
            if (pathSegment != null)
            {
                return pathSegment;
            }

            // Treating as an open property
            return new UnresolvedPathSegment(segment);
        }
 /// <inheritdoc/>
 public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
 {
     return pathSegment.SegmentKind == ODataSegmentKinds.Batch;
 }
 /// <summary>
 /// Matches the template with an <see cref="ODataPathSegment"/>.
 /// </summary>
 /// <param name="pathSegment">The path segment to match this template with.</param>
 /// <param name="values">The dictionary of matches to be updated if the segment matches the template.</param>
 /// <returns><see langword="true"/> if the segment matches the template; otherwise, <see langword="false"/>.</returns>
 public virtual bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
 {
     return false;
 }
Beispiel #32
0
 private void HandleEntitySetPathSegment(ODataPathSegment segment)
 {
     var entitySetPathSegment = (EntitySetPathSegment)segment;
     var entitySet = entitySetPathSegment.EntitySetBase;
     this.currentEntityType = entitySet.EntityType();
     this.queryable = this.api.Source(entitySet.Name, (object[])null);
     this.currentType = this.queryable.ElementType;
 }
 /// <inheritdoc/>
 public override bool TryMatch(ODataPathSegment pathSegment, IDictionary <string, object> values)
 {
     return
         (pathSegment.SegmentKind == ODataSegmentKinds.DynamicProperty &&
          ((DynamicPropertyPathSegment)pathSegment).PropertyName == PropertyName);
 }