/// <summary>
        /// Parses the key properties based on the segment's target type, then creates a new segment for the key.
        /// </summary>
        /// <param name="segment">The segment to apply the key to.</param>
        /// <param name="key">The key to apply.</param>
        /// <returns>The newly created key segment.</returns>
        private static IPathSegment CreateKeySegment(IPathSegment segment, KeyInstance key)
        {
            Debug.Assert(segment != null, "segment != null");
            Debug.Assert(key != null && !key.IsEmpty, "key != null && !key.IsEmpty");
            Debug.Assert(segment.SingleResult == false, "segment.SingleResult == false");

            IEdmEntityType targetEntityType = null;

            WebUtil.CheckSyntaxValid(segment.TargetEdmType != null && segment.TargetEdmType.IsEntityOrEntityCollectionType(out targetEntityType));
            Debug.Assert(targetEntityType != null, "targetEntityType != null");

            // Make sure the keys specified in the uri matches with the number of keys in the metadata
            var keyProperties = targetEntityType.Key().ToList();

            if (keyProperties.Count != key.ValueCount)
            {
                throw ExceptionUtil.CreateBadRequestError(ErrorStrings.BadRequest_KeyCountMismatch(targetEntityType.FullName()));
            }

            if (!key.AreValuesNamed && key.ValueCount > 1)
            {
                throw ExceptionUtil.CreateBadRequestError(ErrorStrings.RequestUriProcessor_KeysMustBeNamed);
            }

            WebUtil.CheckSyntaxValid(key.TryConvertValues(keyProperties));

            return(new PathSegment(segment)
            {
                Key = key,
                SingleResult = true,
            });
        }
        /// <summary>Tries to create a key segment for the given filter if it is non empty.</summary>
        /// <param name="previous">Segment on which to compose.</param>
        /// <param name="filter">Filter portion of segment, possibly null.</param>
        /// <param name="keySegment">The key segment that was created if the key was non-empty.</param>
        /// <returns>Whether the key was non-empty.</returns>
        internal static bool TryCreateKeySegmentFromParentheses(IPathSegment previous, string filter, out IPathSegment keySegment)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(filter != null, "filter != null");
            Debug.Assert(previous != null, "segment!= null");

            WebUtil.CheckSyntaxValid(!previous.SingleResult);

            KeyInstance key;

            WebUtil.CheckSyntaxValid(KeyInstance.TryParseKeysFromUri(filter, out key));

            if (key.IsEmpty)
            {
                keySegment = null;
                return(false);
            }

            keySegment = CreateKeySegment(previous, key);
            return(true);
        }
Beispiel #3
0
        /// <summary>
        /// Gets the target entity set for the given function import.
        /// </summary>
        /// <param name="functionImport">The function import.</param>
        /// <param name="sourceEntitySet">The source entity set.</param>
        /// <param name="model">The model.</param>
        /// <returns>The target entity set of the function import or null if it could not be determined.</returns>
        internal static IEdmEntitySet GetTargetEntitySet(this IEdmFunctionImport functionImport, IEdmEntitySet sourceEntitySet, IEdmModel model)
        {
            DebugUtils.CheckNoExternalCallers();
            IEdmEntitySet targetEntitySet;

            if (functionImport.TryGetStaticEntitySet(out targetEntitySet))
            {
                return(targetEntitySet);
            }

            if (sourceEntitySet == null)
            {
                return(null);
            }

            if (functionImport.IsBindable && functionImport.Parameters.Any())
            {
                IEdmFunctionParameter parameter;
                IEnumerable <IEdmNavigationProperty> path;
                if (functionImport.TryGetRelativeEntitySetPath(model, out parameter, out path))
                {
                    // TODO: throw better exception
                    WebUtil.CheckSyntaxValid(parameter == functionImport.Parameters.First());
                    targetEntitySet = sourceEntitySet;
                    foreach (var navigation in path)
                    {
                        targetEntitySet = targetEntitySet.FindNavigationTarget(navigation);
                        if (targetEntitySet == null)
                        {
                            return(null);
                        }
                    }

                    return(targetEntitySet);
                }
            }

            return(null);
        }