/// <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); }
/// <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); }