コード例 #1
0
        /// <summary>
        /// Adds a navigation property to the <paramref name="entityType"/>. This method creates an association type
        /// in order to add the navigation property.
        /// Returns the modified entity type for composability.
        /// </summary>
        /// <param name="entityType">The <see cref="EntityType"/> to add the navigation property to.</param>
        /// <param name="propertyName">The name of the property to add.</param>
        /// <param name="otherEndType">The type of the other end of the navigation property.</param>
        /// <returns>The <paramref name="entityType"/> instance after adding the navigation property to it.</returns>
        public static EdmEntityType NavigationProperty(this EdmEntityType entityType, string propertyName, EdmEntityType otherEndType)
        {
            ExceptionUtilities.CheckArgumentNotNull(entityType, "entityType");
            ExceptionUtilities.CheckArgumentNotNull(propertyName, "propertyName");

            // Create a navigation property representing one side of an association.
            // The partner representing the other side exists only inside this property and is not added to the target entity type,
            // so it should not cause any name collisions.
            EdmNavigationProperty navProperty = EdmNavigationProperty.CreateNavigationPropertyWithPartner(
                propertyName,
                otherEndType.ToTypeReference(),
                /*dependentProperties*/ null,
                /*principalProperties*/ null,
                /*containsTarget*/ false,
                EdmOnDeleteAction.None,
                "Partner",
                entityType.ToTypeReference(true),
                /*partnerDependentProperties*/ null,
                /*partnerPrincipalProperties*/ null,
                /*partnerContainsTarget*/ false,
                EdmOnDeleteAction.None);

            entityType.AddProperty(navProperty);
            return(entityType);
        }
コード例 #2
0
        /// <summary>Adds a new navigation property.</summary>
        /// <param name="entityType">The entity type to add the property to.</param>
        /// <param name="name">The name of the property to add.</param>
        /// <param name="deleteAction">The delete action of the nav property.</param>
        /// <param name="propertyTypeReference">The type of the property to add.</param>
        /// <param name="propertyInfo">If this is a CLR property, the <see cref="PropertyInfo"/> for the property, or null otherwise.</param>
        /// <param name="containsTarget">The contains target of the nav property</param>
        /// <returns>The newly created and added property.</returns>
        private IEdmNavigationProperty AddNavigationProperty(
            IEdmEntityType entityType,
            string name,
            EdmOnDeleteAction deleteAction,
            IEdmTypeReference propertyTypeReference,
            bool containsTarget)
        {
            // Create a navigation property representing one side of an association.
            // The partner representing the other side exists only inside this property and is not added to the target entity type,
            // so it should not cause any name collisions.
            EdmNavigationProperty navProperty = EdmNavigationProperty.CreateNavigationPropertyWithPartner(
                name,
                propertyTypeReference,
                /*dependentProperties*/ null,
                /*principalProperties*/ null,
                containsTarget,
                deleteAction,
                "Partner",
                entityType.ToTypeReference(true),
                /*partnerDependentProperties*/ null,
                /*partnerPrincipalProperties*/ null,
                /*partnerContainsTarget*/ false,
                EdmOnDeleteAction.None);

            ((EdmStructuredType)entityType).AddProperty(navProperty);

            return(navProperty);
        }
コード例 #3
0
        /// <summary>
        /// Creates an Edm property.
        /// </summary>
        /// <param name="declaringType">Type declaring this property.</param>
        /// <param name="propertyInfo">PropertyInfo instance for this property.</param>
        /// <returns>Returns a new instance of Edm property.</returns>
        private IEdmProperty CreateEdmProperty(IEdmStructuredType declaringType, PropertyInfo propertyInfo)
        {
            IEdmType propertyEdmType = this.GetOrCreateEdmType(propertyInfo.PropertyType);

            Debug.Assert(
                propertyEdmType.TypeKind == EdmTypeKind.Entity ||
                propertyEdmType.TypeKind == EdmTypeKind.Complex ||
                propertyEdmType.TypeKind == EdmTypeKind.Enum ||
                propertyEdmType.TypeKind == EdmTypeKind.Primitive ||
                propertyEdmType.TypeKind == EdmTypeKind.Collection,
                "Property kind should be Entity, Complex, Enum, Primitive or Collection.");

            IEdmProperty edmProperty        = null;
            bool         isPropertyNullable = ClientTypeUtil.CanAssignNull(propertyInfo.PropertyType);

            if (propertyEdmType.TypeKind == EdmTypeKind.Entity || (propertyEdmType.TypeKind == EdmTypeKind.Collection && ((IEdmCollectionType)propertyEdmType).ElementType.TypeKind() == EdmTypeKind.Entity))
            {
                if (declaringType.TypeKind == EdmTypeKind.Entity || declaringType.TypeKind == EdmTypeKind.Complex)
                {
                    if (declaringType as IEdmEntityType == null && declaringType as IEdmComplexType == null)
                    {
                        throw c.Error.InvalidOperation(c.Strings.ClientTypeCache_NonEntityTypeOrNonComplexTypeCannotContainEntityProperties(propertyInfo.Name, propertyInfo.DeclaringType.ToString()));
                    }

                    // Create a navigation property representing one side of an association.
                    // The partner representing the other side exists only inside this property and is not added to the target entity type,
                    // so it should not cause any name collisions.
                    edmProperty = EdmNavigationProperty.CreateNavigationPropertyWithPartner(
                        ClientTypeUtil.GetServerDefinedName(propertyInfo),
                        propertyEdmType.ToEdmTypeReference(isPropertyNullable),
                        /*dependentProperties*/ null,
                        /*principalProperties*/ null,
                        /*containsTarget*/ false,
                        EdmOnDeleteAction.None,
                        "Partner",
                        declaringType.ToEdmTypeReference(true),
                        /*partnerDependentProperties*/ null,
                        /*partnerPrincipalProperties*/ null,
                        /*partnerContainsTarget*/ false,
                        EdmOnDeleteAction.None);
                }
            }
            else
            {
                edmProperty = new EdmStructuralProperty(declaringType, ClientTypeUtil.GetServerDefinedName(propertyInfo), propertyEdmType.ToEdmTypeReference(isPropertyNullable));
            }

            edmProperty.SetClientPropertyAnnotation(new ClientPropertyAnnotation(edmProperty, propertyInfo, this));
            return(edmProperty);
        }
コード例 #4
0
        public void TestElementInterfaceCriticalEnumPropertyValueOutOfRange()
        {
            var expectedErrors = new EdmLibTestErrors()
            {
                { null, null, EdmErrorCode.InterfaceCriticalEnumPropertyValueOutOfRange }
            };

            var entity      = new EdmEntityType("DefaultNamespace", "Entity");
            var navProperty = EdmNavigationProperty.CreateNavigationPropertyWithPartner(
                "Navigation", new EdmEntityTypeReference(entity, false /*isNullable*/), null /*dependentProperties*/, null /*principalProperties*/, false /*containsTarget*/, (EdmOnDeleteAction)123,
                "", new EdmEntityTypeReference(entity, false /*isNullable*/), null /*partnerDependentProperties*/, null /*partnerPrincipalProperties*/, false /*partnerContainsTarget*/, EdmOnDeleteAction.Cascade);

            entity.AddProperty(navProperty);
            this.ValidateElement(navProperty, expectedErrors);
        }
コード例 #5
0
        public void TestNavigationBothNotPrincipalRoundTrip()
        {
            var model = new EdmModel();

            var person   = new EdmEntityType("NS", "Person");
            var personId = person.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false));

            person.AddKeys(personId);
            model.AddElement(person);

            var pet   = new EdmEntityType("NS", "Pet");
            var petId = new EdmStructuralProperty(pet, "Id", EdmCoreModel.Instance.GetInt32(false));

            pet.AddProperty(petId);
            pet.AddKeys(petId);
            model.AddElement(pet);

            var personToPet = EdmNavigationProperty.CreateNavigationPropertyWithPartner(
                new EdmNavigationPropertyInfo()
            {
                Name = "ToPet", Target = pet, TargetMultiplicity = EdmMultiplicity.One, ContainsTarget = true
            },
                new EdmNavigationPropertyInfo()
            {
                Name = "ToPerson", Target = person, TargetMultiplicity = EdmMultiplicity.One
            });

            pet.AddProperty(personToPet.Partner);
            person.AddProperty(personToPet);

            Assert.IsFalse(personToPet.IsPrincipal(), "Invalid navigation principal value.");
            Assert.IsFalse(personToPet.Partner.IsPrincipal(), "Invalid navigation principal value.");

            var csdls          = this.GetSerializerResult(model);
            var roundTripModel = this.GetParserResult(csdls);

            var roundTripPerson = roundTripModel.FindEntityType("NS.Person");

            Assert.IsNotNull(roundTripPerson, "Invalid entity type.");
            var roundTripNavs = roundTripPerson.NavigationProperties();

            Assert.AreEqual(1, roundTripNavs.Count(), "Invalid navigation property count.");
            var roundTripNav = roundTripNavs.First();

            Assert.IsFalse(roundTripNav.IsPrincipal(), "Invalid navigation principal value.");
            Assert.IsFalse(roundTripNav.Partner.IsPrincipal(), "Invalid navigation principal value.");
        }
コード例 #6
0
        public void DeclaringTypeOFAnEntityNavigationCanBeAComplexType()
        {
            //Arrange
            Type        complexDeclaringType      = typeof(Address);
            Type        entityNavigationType      = typeof(City);
            EdmTypeKind expectedDeclaringTypeKind = EdmTypeKind.Complex;

            //Act
            ClientEdmModel        clientEdmModel = new ClientEdmModel(ODataProtocolVersion.V401);
            IEdmType              edmTypeOfComplexDeclaringType = clientEdmModel.GetOrCreateEdmType(complexDeclaringType);
            IEdmType              edmTypeOfEntityNavigationType = clientEdmModel.GetOrCreateEdmType(entityNavigationType);
            IEdmStructuredType    entiyNavigationType           = clientEdmModel.GetOrCreateEdmType(complexDeclaringType) as IEdmStructuredType;
            EdmNavigationProperty edmNavigationProperty         = EdmNavigationProperty.CreateNavigationPropertyWithPartner("City", ClientTypeUtil.ToEdmTypeReference(edmTypeOfEntityNavigationType, true), null, null, false, EdmOnDeleteAction.None, "Partner", ClientTypeUtil.ToEdmTypeReference(edmTypeOfComplexDeclaringType, true), null, null, false, EdmOnDeleteAction.None);
            EdmTypeKind           resultingDeclaringTypeKind    = edmNavigationProperty.DeclaringType.TypeKind;

            //Assert
            Assert.Equal(expectedDeclaringTypeKind, resultingDeclaringTypeKind);
        }
コード例 #7
0
 private IEnumerable <IEdmElement> GetEdmAnnotatables()
 {
     return(new IEdmElement[] {
         new EdmComplexType("", ""),
         new EdmEntityContainer("", ""),
         new EdmEntityType("", ""),
         new EdmEntitySet(new EdmEntityContainer("", ""), "", new EdmEntityType("", "")),
         EdmNavigationProperty.CreateNavigationPropertyWithPartner(
             new EdmNavigationPropertyInfo()
         {
             Name = "", Target = new EdmEntityType("", ""), TargetMultiplicity = EdmMultiplicity.One
         },
             new EdmNavigationPropertyInfo()
         {
             Name = "", Target = new EdmEntityType("", ""), TargetMultiplicity = EdmMultiplicity.One
         }),
         new EdmStructuredValue(null, Enumerable.Empty <IEdmPropertyValue>()),
         new EdmStringConstant(null, ""),
         new EdmStructuralProperty(new EdmComplexType("", ""), "", EdmCoreModel.Instance.GetBoolean(true)),
     });
 }
コード例 #8
0
        private IEdmProperty CreateEdmProperty(IEdmStructuredType declaringType, PropertyInfo propertyInfo)
        {
            IEdmProperty property;
            IEdmType     edmType    = this.GetOrCreateEdmTypeInternal(propertyInfo.PropertyType).EdmType;
            bool         isNullable = ClientTypeUtil.CanAssignNull(propertyInfo.PropertyType);

            if ((edmType.TypeKind == EdmTypeKind.Entity) || ((edmType.TypeKind == EdmTypeKind.Collection) && (((IEdmCollectionType)edmType).ElementType.TypeKind() == EdmTypeKind.Entity)))
            {
                IEdmEntityType type2 = declaringType as IEdmEntityType;
                if (type2 == null)
                {
                    throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.ClientTypeCache_NonEntityTypeCannotContainEntityProperties(propertyInfo.Name, propertyInfo.DeclaringType.ToString()));
                }
                property = EdmNavigationProperty.CreateNavigationPropertyWithPartner(propertyInfo.Name, edmType.ToEdmTypeReference(isNullable), null, false, EdmOnDeleteAction.None, "Partner", type2.ToEdmTypeReference(true), null, false, EdmOnDeleteAction.None);
            }
            else
            {
                property = new EdmStructuralProperty(declaringType, propertyInfo.Name, edmType.ToEdmTypeReference(isNullable));
            }
            property.SetClientPropertyAnnotation(new ClientPropertyAnnotation(property, propertyInfo, this.protocolVersion));
            return(property);
        }
コード例 #9
0
        public void TestElementError()
        {
            var expectedErrors = new EdmLibTestErrors();

            this.ValidateElement(new EdmModel(), expectedErrors);
            this.ValidateElement(new EdmTerm("foo", "bar", EdmCoreModel.Instance.GetInt32(false)), expectedErrors);
            this.ValidateElement(new EdmEntityType("", ""), expectedErrors);
            this.ValidateElement(new EdmComplexType("", ""), expectedErrors);
            this.ValidateElement(new EdmFunction("foo", "bar", EdmCoreModel.Instance.GetStream(true)), expectedErrors);
            this.ValidateElement(new EdmFunctionImport(new EdmEntityContainer("", ""), "foo", new EdmFunction("namespace", "foo", EdmCoreModel.Instance.GetInt32(false))), expectedErrors);
            this.ValidateElement(new EdmEntityType("", "").AddStructuralProperty("foo", EdmCoreModel.Instance.GetString(true)), expectedErrors);
            this.ValidateElement(new EdmEntitySet(new EdmEntityContainer("", ""), "foo", new EdmEntityType("", "")), expectedErrors);
            this.ValidateElement(new EdmEnumType("", ""), expectedErrors);
            this.ValidateElement(EdmNavigationProperty.CreateNavigationPropertyWithPartner(
                                     new EdmNavigationPropertyInfo()
            {
                Name = "", Target = new EdmEntityType("", ""), TargetMultiplicity = EdmMultiplicity.One
            },
                                     new EdmNavigationPropertyInfo()
            {
                Name = "", Target = new EdmEntityType("", ""), TargetMultiplicity = EdmMultiplicity.One
            }), expectedErrors);
        }
コード例 #10
0
        /// <summary>
        /// Creates an Edm property.
        /// </summary>
        /// <param name="declaringType">Type declaring this property.</param>
        /// <param name="propertyInfo">PropertyInfo instance for this property.</param>
        /// <returns>Returns a new instance of Edm property.</returns>
        private IEdmProperty CreateEdmProperty(IEdmStructuredType declaringType, PropertyInfo propertyInfo)
        {
            IEdmType propertyEdmType = this.GetOrCreateEdmTypeInternal(propertyInfo.PropertyType).EdmType;

            Debug.Assert(
                propertyEdmType.TypeKind == EdmTypeKind.Entity ||
                propertyEdmType.TypeKind == EdmTypeKind.Complex ||
                propertyEdmType.TypeKind == EdmTypeKind.Primitive ||
                propertyEdmType.TypeKind == EdmTypeKind.Collection,
                "Property kind should be Entity, Complex, Primitive or Collection.");

            IEdmProperty edmProperty;
            bool         isPropertyNullable = ClientTypeUtil.CanAssignNull(propertyInfo.PropertyType);

            if (propertyEdmType.TypeKind == EdmTypeKind.Entity || (propertyEdmType.TypeKind == EdmTypeKind.Collection && ((IEdmCollectionType)propertyEdmType).ElementType.TypeKind() == EdmTypeKind.Entity))
            {
                IEdmEntityType declaringEntityType = declaringType as IEdmEntityType;
                if (declaringEntityType == null)
                {
                    throw c.Error.InvalidOperation(c.Strings.ClientTypeCache_NonEntityTypeCannotContainEntityProperties(propertyInfo.Name, propertyInfo.DeclaringType.ToString()));
                }

                // Create a navigation property representing one side of an association.
                // The partner representing the other side exists only inside this property and is not added to the target entity type,
                // so it should not cause any name collisions.
                edmProperty = EdmNavigationProperty.CreateNavigationPropertyWithPartner(
                    propertyInfo.Name,
                    propertyEdmType.ToEdmTypeReference(isPropertyNullable),
                    /*dependentProperties*/ null,
                    /*containsTarget*/ false,
                    EdmOnDeleteAction.None,
                    "Partner",
                    declaringEntityType.ToEdmTypeReference(true),
                    /*partnerDependentProperties*/ null,
                    /*partnerContainsTarget*/ false,
                    EdmOnDeleteAction.None);
            }
            else
            {
                edmProperty = new EdmStructuralProperty(declaringType, propertyInfo.Name, propertyEdmType.ToEdmTypeReference(isPropertyNullable));
            }

            FieldInfo backingField = null;

            if (this.ResolveBackingField != null)
            {
                // We only do this for "collections of entities" OR "complex properties"
                if (propertyEdmType.TypeKind == EdmTypeKind.Collection && !propertyEdmType.IsPrimitive() || propertyEdmType.TypeKind == EdmTypeKind.Complex)
                {
                    backingField = this.ResolveBackingField(propertyInfo);
                }

                if (backingField != null && backingField.FieldType != propertyInfo.PropertyType)
                {
                    backingField = null; // We disregard returned FieldInfo that has the wrong type.
                }
            }

            edmProperty.SetClientPropertyAnnotation(new ClientPropertyAnnotation(edmProperty, propertyInfo, backingField, this));
            return(edmProperty);
        }