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