Пример #1
0
        /// <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));
        }
Пример #2
0
        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()));
        }