/// <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="previousKeySegment">The parent node's key segment.</param> /// <param name="key">The key to apply.</param> /// <param name="resolver">The resolver to use.</param> /// <returns>The newly created key segment.</returns> private static KeySegment CreateKeySegment(ODataPathSegment segment, KeySegment previousKeySegment, SegmentArgumentParser key, ODataUriResolver resolver) { 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; if (!(segment.TargetEdmType != null && segment.TargetEdmType.IsEntityOrEntityCollectionType(out targetEntityType))) { throw ExceptionUtil.CreateSyntaxError(); } 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) { NavigationPropertySegment currentNavPropSegment = segment as NavigationPropertySegment; if (currentNavPropSegment != null) { key = KeyFinder.FindAndUseKeysFromRelatedSegment(key, keyProperties, currentNavPropSegment.NavigationProperty, previousKeySegment); } // if we still didn't find any keys, then throw an error. if (keyProperties.Count != key.ValueCount && resolver.GetType() == typeof(ODataUriResolver)) { throw ExceptionUtil.CreateBadRequestError(ErrorStrings.BadRequest_KeyCountMismatch(targetEntityType.FullName())); } } if (!key.AreValuesNamed && key.ValueCount > 1 && resolver.GetType() == typeof(ODataUriResolver)) { throw ExceptionUtil.CreateBadRequestError(ErrorStrings.RequestUriProcessor_KeysMustBeNamed); } IEnumerable <KeyValuePair <string, object> > keyPairs; if (!key.TryConvertValues(targetEntityType, out keyPairs, resolver)) { throw ExceptionUtil.CreateSyntaxError(); } return(new KeySegment(segment, keyPairs, targetEntityType, segment.TargetEdmNavigationSource)); }
public void KeyCannotBeImplicitIfNotSpecifiedByReferentialIntegrityConstraint() { ODataPathSegment keySegment; Action implicitKeyWithOutRefIntegrityConstraint = () => SegmentKeyHandler.TryCreateKeySegmentFromParentheses( new NavigationPropertySegment( HardCodedTestModel.GetPersonMyLionsNavProp(), HardCodedTestModel.GetLionSet()), new KeySegment(new List <KeyValuePair <string, object> >() { new KeyValuePair <string, object>("AttackDates", "0") }, HardCodedTestModel.GetPersonType(), HardCodedTestModel.GetPeopleSet()), "10", DefaultUriResolver, out keySegment); implicitKeyWithOutRefIntegrityConstraint.Throws <ODataException>(ODataErrorStrings.BadRequest_KeyCountMismatch(HardCodedTestModel.GetLionType().FullTypeName())); }