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