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