Beispiel #1
0
        /// <summary>
        /// Creates metadata properties for the specified enumeration of OData OM properties.
        /// </summary>
        /// <param name="model">The model to use.</param>
        /// <param name="owningType">The owning type to which to add the properties.</param>
        /// <param name="properties">Enumeration of the properties to add.</param>
        private static void CreateMetadataProperties(EntityModelSchema model, NamedStructuralType owningType, IEnumerable<ODataProperty> properties)
        {
            if (properties == null)
            {
                return;
            }

            foreach (ODataProperty property in properties)
            {
                ODataPropertyMetadataAnnotation propertyMetadataAnnotation = property.GetInheritedAnnotation<ODataPropertyMetadataAnnotation>();

                object propertyValue = property.Value;
                bool isOpenProperty = false;
                if (propertyMetadataAnnotation != null)
                {
                    isOpenProperty = propertyMetadataAnnotation.IsOpenProperty;
                    ExceptionUtilities.Assert(
                        !isOpenProperty || owningType is EntityType,
                        "Can't declare an open property on non-entity type.");
                    if (propertyMetadataAnnotation.PropertyValueForTypeInference != null)
                    {
                        propertyValue = propertyMetadataAnnotation.PropertyValueForTypeInference;
                    }
                }

                ODataComplexValue complexValue = propertyValue as ODataComplexValue;
                if (complexValue != null)
                {
                    ExceptionUtilities.Assert(complexValue.TypeName.StartsWith(owningType.NamespaceName + "."), "The type name must start with the same namespace as its owning type.");

                    ComplexType complexType = model.GetComplexType(complexValue.TypeName);
                    if (complexType == null)
                    {
                        string complexTypeLocalName = complexValue.TypeName.Substring(owningType.NamespaceName.Length + 1);
                        complexType = model.ComplexType(complexTypeLocalName, owningType.NamespaceName);
                        CreateMetadataProperties(model, complexType, complexValue.Properties);
                    }

                    if (isOpenProperty)
                    {
                        owningType.IsOpen = true;
                    }
                    else
                    {
                        owningType.Property(property.Name, DataTypes.ComplexType.WithDefinition(complexType).Nullable());
                    }
                }
                else
                {
                    bool isKeyProperty = false;
                    bool isETagProperty = false;
                    if (propertyMetadataAnnotation != null)
                    {
                        isKeyProperty = (propertyMetadataAnnotation.Kind & ODataPropertyKind.Key) == ODataPropertyKind.Key;
                        isETagProperty = (propertyMetadataAnnotation.Kind & ODataPropertyKind.ETag) == ODataPropertyKind.ETag;

                        ExceptionUtilities.Assert(
                            !isKeyProperty || owningType is EntityType,
                            "Can't declare a key property on non-entity type.");
                        ExceptionUtilities.Assert(
                            !isETagProperty || owningType is EntityType,
                            "Can't declare an etag property on non-entity type.");
                        ExceptionUtilities.Assert(
                            !isOpenProperty || !(isKeyProperty || isETagProperty),
                            "Key or etag property can't be open.");
                    }

                    if (owningType is EntityType && isOpenProperty)
                    {
                        owningType.IsOpen = true;
                    }
                    else
                    {
                        EntityType owningEntityType = owningType as EntityType;
                        if (owningEntityType != null && isKeyProperty)
                        {
                            ExceptionUtilities.Assert(
                                propertyValue != null,
                                "Found a key property with null value, can't infer type from value in that case and it's invalid anyway.");
                            PrimitiveDataType keyPropertyType = EntityModelUtils.GetPrimitiveEdmType(propertyValue.GetType());
                            owningEntityType.KeyProperty(property.Name, keyPropertyType, isETagProperty);
                        }
                        else
                        {
                            if (propertyValue is ODataCollectionValue)
                            {
                                string itemTypeName = EntityModelUtils.GetCollectionItemTypeName(((ODataCollectionValue)propertyValue).TypeName);
                                CollectionDataType collectionType = null;
                                DataType primitiveItemType = EntityModelUtils.GetPrimitiveEdmType(itemTypeName);
                                if (primitiveItemType != null)
                                {
                                    collectionType = DataTypes.CollectionType.WithElementDataType(primitiveItemType);
                                }
                                else
                                {
                                    ComplexType complexItemType = model.GetComplexType(itemTypeName);
                                    collectionType = DataTypes.CollectionOfComplex(complexItemType);
                                }

                                ExceptionUtilities.Assert(collectionType != null, "Could not resolve item type.");
                                owningType.Property(property.Name, collectionType);
                            }
                            else
                            {
                                Type propertyType = propertyValue == null
                                    ? typeof(string)
                                    : propertyValue.GetType();
                                PrimitiveDataType edmPropertyType = EntityModelUtils.GetPrimitiveEdmType(propertyType);

                                owningType.Property(property.Name, edmPropertyType, isETagProperty);
                            }
                        }
                    }
                }
            }
        }