/// <summary>
        /// Creates an <see cref="IEdmModel"/> based on a combination of the ObjectContext's properties and it's metadata workspace
        /// </summary>
        /// <param name="context">The object context instance</param>
        /// <returns>An <see cref="IEdmModel"/> based on a combination of the ObjectContext's properties and it's metadata workspace</returns>
        public static IEdmModel CreateModel(ObjectContext context)
        {
            Assembly objectLayerAssembly = context.GetType().Assembly;
            ConstructableMetadata metadata = new ConstructableMetadata(context.DefaultContainerName, ("DBNorthwindModel"));
            foreach (EntityType entityType in context.MetadataWorkspace.GetItems<EntityType>(DataSpace.CSpace))
            {
                Type clrType = objectLayerAssembly.GetType("Microsoft.Test.Taupo.OData.WCFService.Model." + entityType.Name, false, true);
                IEdmEntityType edmEntityType = metadata.AddEntityType(entityType.Name, clrType, null, false, "DBNorthwindModel");
                AddProperties(metadata, entityType.Properties, edmEntityType);
            }

            foreach (var entitySet in context.GetType().GetProperties().Where(property => property.PropertyType.GetInterface("IQueryable") != null))
            {
                Type entityType = entitySet.PropertyType.GetGenericArguments().First();
                IEdmEntityType edmEntityType = metadata.FindType("DBNorthwindModel." + entityType.Name) as IEdmEntityType;
                metadata.AddEntitySet(entitySet.Name, edmEntityType);
            }

            return metadata;
        }
 /// <summary>
 /// Adds Associations to the EDM model based on an Entity Data Model Schema
 /// </summary>
 /// <param name="model">EDM model to append to</param>
 /// <param name="model">Entity Data Model Schema to get associations from</param>
 private static void AddNavigationProperties(ConstructableMetadata model, IEdmEntityType entityType, IEnumerable<NavigationProperty> properties)
 {
     foreach (NavigationProperty property in properties)
     {
         if (property.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
         {
             model.AddResourceSetReferenceProperty(
                 entityType,
                 property.Name,
                 model.FindEntitySet(property.ToEndMember.GetEntityType().Name),
                 model.FindType(property.ToEndMember.GetEntityType().FullName) as IEdmEntityType
             );
         }
         else
         {
             model.AddResourceReferenceProperty(
                 entityType,
                 property.Name,
                 model.FindEntitySet(property.ToEndMember.GetEntityType().Name),
                 model.FindType(property.ToEndMember.GetEntityType().FullName) as IEdmEntityType
             );
         }
     }
 }
 /// <summary>
 /// Adds a Primitive Property to <paramref name="metadata"/>
 /// </summary>
 /// <param name="metadata">Metadata document to be added to</param>
 /// <param name="type">The type of the primitive property</param>
 /// <param name="property">Property to add</param>
 /// <param name="structuredType">Structured type to add property to</param>
 private static void AddPrimitiveProperty(ConstructableMetadata metadata, Type type, EdmProperty property, IEdmStructuredType structuredType)
 {
     if (property.DeclaringType is EntityType && ((EntityType)property.DeclaringType).KeyMembers.Contains(property.Name))
     {
         metadata.AddKeyProperty(structuredType, property.Name, type, IsETagProperty(property));
     }
     else if (type == typeof(Stream))
     {
         metadata.AddNamedStreamProperty(structuredType, property.Name);
     }
     else
     {
         metadata.AddPrimitiveProperty(structuredType, property.Name, type, IsETagProperty(property));
     }
 }
 /// <summary>
 /// Adds the <paramref name="properties"/> to the <paramref name="metadata"/>
 /// Recursively calls self to add complex types as needed
 /// </summary>
 /// <param name="metadata">The metadata document to add properties to</param>
 /// <param name="properties">The properties to add to the metadata document</param>
 /// <param name="structuredType">The type that these elements belong to</param>
 private static void AddProperties(ConstructableMetadata metadata, IEnumerable<EdmProperty> properties, IEdmStructuredType structuredType)
 {
     foreach (EdmProperty property in properties)
     {
         AddProperty(metadata, property, structuredType);
     }
 }
Esempio n. 5
0
        /// <summary>
        /// Gets the edm model. Constructs it if it doesn't exist
        /// </summary>
        /// <returns>Edm model</param>
        public IEdmModel GetModel()
        {
            if (this.model == null)
            {
                ConstructableMetadata metadata = new ConstructableMetadata("InMemoryEntities", "Microsoft.Test.Taupo.OData.WCFService");
                IEdmComplexType addressType = metadata.AddComplexType("Address", typeof(Address), null, false);
                metadata.AddPrimitiveProperty(addressType, "Street", typeof(string));
                metadata.AddPrimitiveProperty(addressType, "City", typeof(string));
                metadata.AddPrimitiveProperty(addressType, "PostalCode", typeof(string));

                IEdmComplexType homeAddressType = metadata.AddComplexType("HomeAddress", typeof(HomeAddress), addressType, false);
                metadata.AddPrimitiveProperty(homeAddressType, "HomeNO", typeof(string));

                IEdmEntityType personType = metadata.AddEntityType("Person", typeof(Person), null, false, "Microsoft.Test.Taupo.OData.WCFService");
                metadata.AddKeyProperty(personType, "PersonID", typeof(Int32));
                metadata.AddPrimitiveProperty(personType, "FirstName", typeof(string));
                metadata.AddPrimitiveProperty(personType, "LastName", typeof(string));
                metadata.AddComplexProperty(personType, "HomeAddress", addressType);
                metadata.AddPrimitiveProperty(personType, "Home", typeof(GeographyPoint));
                metadata.AddMultiValueProperty(personType, "Numbers", typeof(string));
                metadata.AddContainedResourceSetReferenceProperty(personType, "Brother", personType);
                metadata.AddContainedResourceReferenceProperty(personType, "Child", personType);
                var peopleset = metadata.AddEntitySet("People", personType);
                var specialPerson = metadata.AddSingleton("SpecialPerson", personType);

                IEdmEntityType customerType = metadata.AddEntityType("Customer", typeof(Customer), personType, false, "Microsoft.Test.Taupo.OData.WCFService");
                metadata.AddPrimitiveProperty(customerType, "City", typeof(string));
                metadata.AddPrimitiveProperty(customerType, "Birthday", typeof(DateTimeOffset));
                metadata.AddPrimitiveProperty(customerType, "TimeBetweenLastTwoOrders", typeof(TimeSpan));
                var customerset = metadata.AddEntitySet("Customers", customerType);
                var vipCustomer = metadata.AddSingleton("VipCustomer", customerType);

                IEdmEntityType employeeType = metadata.AddEntityType("Employee", typeof(Employee), personType, false, "Microsoft.Test.Taupo.OData.WCFService", true);
                metadata.AddPrimitiveProperty(employeeType, "DateHired", typeof(DateTimeOffset));
                metadata.AddPrimitiveProperty(employeeType, "Office", typeof(GeographyPoint));
                var employeeset = metadata.AddEntitySet("Employees", employeeType);
                var boss = metadata.AddSingleton("Boss", employeeType);

                IEdmEntityType productType = metadata.AddEntityType("Product", typeof(Product), null, false, "Microsoft.Test.Taupo.OData.WCFService");
                metadata.AddKeyProperty(productType, "ProductID", typeof(Int32));
                metadata.AddPrimitiveProperty(productType, "Name", typeof(string));
                metadata.AddPrimitiveProperty(productType, "QuantityPerUnit", typeof(string));
                metadata.AddPrimitiveProperty(productType, "UnitPrice", typeof(float));
                metadata.AddPrimitiveProperty(productType, "QuantityInStock", typeof(Int32));
                metadata.AddPrimitiveProperty(productType, "Discontinued", typeof(bool));
                metadata.AddComplexProperty(productType, "ManufactureAddresss", addressType, true);
                var productset = metadata.AddEntitySet("Products", productType);
                var specialProduct = metadata.AddSingleton("SpecialProduct", productType);

                IEdmEntityType orderType = metadata.AddEntityType("Order", typeof(Order), null, false, "Microsoft.Test.Taupo.OData.WCFService");
                var orderset = metadata.AddEntitySet("Orders", orderType);
                metadata.AddKeyProperty(orderType, "OrderID", typeof(Int32));
                metadata.AddPrimitiveProperty(orderType, "CustomerID", typeof(Int32));
                metadata.AddPrimitiveProperty(orderType, "EmployeeID", typeof(Int32?));
                metadata.AddPrimitiveProperty(orderType, "OrderDate", typeof(DateTimeOffset));
                metadata.AddResourceReferenceProperty(orderType, "LoggedInEmployee", employeeset, null);
                metadata.AddResourceReferenceProperty(orderType, "CustomerForOrder", customerset, null);
                var specialOrder = metadata.AddSingleton("SpecialOrder", orderType);

                metadata.AddContainedResourceReferenceProperty(personType, "FirstOrder", orderType);

                IEdmEntityType orderDetailType = metadata.AddEntityType("OrderDetail", typeof(OrderDetail), null, false, "Microsoft.Test.Taupo.OData.WCFService");
                metadata.AddKeyProperty(orderDetailType, "OrderID", typeof(Int32));
                metadata.AddKeyProperty(orderDetailType, "ProductID", typeof(Int32));
                metadata.AddPrimitiveProperty(orderDetailType, "OrderPlaced", typeof(DateTimeOffset));
                metadata.AddPrimitiveProperty(orderDetailType, "Quantity", typeof(Int32));
                metadata.AddPrimitiveProperty(orderDetailType, "UnitPrice", typeof(float));
                var productOrderedNavigation = metadata.AddResourceReferenceProperty(orderDetailType, "ProductOrdered", productset, null);
                var associatedOrderNavigation = metadata.AddResourceReferenceProperty(orderDetailType, "AssociatedOrder", orderset, null);
                var orderdetailsSet = metadata.AddEntitySet("OrderDetails", orderDetailType);

                // Edm.Duration
                IEdmEntityType durationInKeyType = metadata.AddEntityType("DurationInKey", typeof(DurationInKey), null, false, "Microsoft.Test.Taupo.OData.WCFService");
                metadata.AddKeyProperty(durationInKeyType, "Id", typeof(TimeSpan));
                metadata.AddEntitySet("DurationInKeys", durationInKeyType);

                // FUNCTIONS
                // Function that binds to single order
                metadata.AddFunctionAndFunctionImport("GetOrderRate", orderType.ToTypeReference(), MetadataUtils.GetPrimitiveTypeReference(typeof (Int32)), null, true);

                //Function that binds to a single order and returns a single order
                metadata.AddFunction("GetNextOrder", orderType.ToTypeReference(), orderType.ToTypeReference(), true, new EdmPathExpression("bindingparameter"), true);

                // Function that returns a set of orders

                var collectionOrders = new EdmCollectionType(orderType.ToTypeReference()).ToTypeReference();
                metadata.AddFunction("OrdersWithMoreThanTwoItems", collectionOrders, collectionOrders, true, new EdmPathExpression("bindingparameter"), true /*iscomposable*/);
                
                var overload1Function = metadata.AddFunction("OrdersWithMoreThanTwoItems", collectionOrders, collectionOrders, true, new EdmPathExpression("bindingparameter"), true /*iscomposable*/);
                overload1Function.AddParameter("IntParameter", MetadataUtils.GetPrimitiveTypeReference(typeof (Int32)));

                var overload2Function = metadata.AddFunction("OrdersWithMoreThanTwoItems", collectionOrders, collectionOrders, true, new EdmPathExpression("bindingparameter"), true /*iscomposable*/);
                overload2Function.AddParameter("IntParameter", MetadataUtils.GetPrimitiveTypeReference(typeof(Int32)));
                overload2Function.AddParameter("EntityParameter", productType.ToTypeReference());

                var collectionCustomers = new EdmCollectionType(customerType.ToTypeReference()).ToTypeReference();
                var customersInCityFunction = metadata.AddFunction("InCity", collectionCustomers, collectionCustomers, true, new EdmPathExpression("bindingparameter"), true /*iscomposable*/);
                customersInCityFunction.AddParameter("City", MetadataUtils.GetPrimitiveTypeReference(typeof(String)));

                var customersWithinFunction = metadata.AddFunction("Within", collectionCustomers, collectionCustomers, true, new EdmPathExpression("bindingparameter"), true /*iscomposable*/);
                customersWithinFunction.AddParameter("Location", MetadataUtils.GetPrimitiveTypeReference(typeof(GeographyPoint)));
                customersWithinFunction.AddParameter("Address", addressType.ToTypeReference(true /*nullable*/));
                customersWithinFunction.AddParameter("Distance", MetadataUtils.GetPrimitiveTypeReference(typeof(Double)));
                customersWithinFunction.AddParameter("ArbitraryInt", MetadataUtils.GetPrimitiveTypeReference(typeof(Int32)));
                customersWithinFunction.AddParameter("DateTimeOffset", MetadataUtils.GetPrimitiveTypeReference(typeof(DateTimeOffset?)));
                customersWithinFunction.AddParameter("Byte", MetadataUtils.GetPrimitiveTypeReference(typeof(Byte)));
                customersWithinFunction.AddParameter("LineString", MetadataUtils.GetPrimitiveTypeReference(typeof(GeometryLineString)));

                var withinFunction = metadata.AddFunction("Within", customerType.ToTypeReference(), MetadataUtils.GetPrimitiveTypeReference(typeof(bool)), true, null, true /*iscomposable*/);
                withinFunction.AddParameter("Location", addressType.ToTypeReference());
                withinFunction.AddParameter("Distance", MetadataUtils.GetPrimitiveTypeReference(typeof(Int32)));

                var withinFunction2 = metadata.AddFunction("Within", customerType.ToTypeReference(), MetadataUtils.GetPrimitiveTypeReference(typeof(bool)), true, null, true /*iscomposable*/);
                withinFunction2.AddParameter("Distance", MetadataUtils.GetPrimitiveTypeReference(typeof(Int32)));

                metadata.AddFunction("GetChild", personType.ToTypeReference(), personType.ToTypeReference(), true, new EdmPathExpression("bindingparameter/Child"), true /*iscomposable*/);
                metadata.AddAction("GetBrothers", personType.ToTypeReference(), new EdmCollectionTypeReference(new EdmCollectionType(personType.ToTypeReference())), true, new EdmPathExpression("bindingparameter/Child"));

                //Unbound Functions
                var lotsofOrders = metadata.AddFunctionAndFunctionImport("HasLotsOfOrders",
                   null,
                   MetadataUtils.GetPrimitiveTypeReference(typeof(bool)),
                   null,
                   false /*isBindable*/);

                lotsofOrders.Function.AsEdmFunction().AddParameter("Person", personType.ToTypeReference());

                metadata.AddFunctionAndFunctionImport("HowManyPotatoesEaten", null, MetadataUtils.GetPrimitiveTypeReference(typeof(Int32)), null, false);
                metadata.AddFunctionAndFunctionImport("QuoteOfTheDay", null, MetadataUtils.GetPrimitiveTypeReference(typeof(string)), null, false);

                // ACTIONS
                var action1 = metadata.AddAction("ChangeAddress", personType.ToTypeReference(), null /*returnType*/, true /*isbound*/, null /*entitySetPathExpression*/);
                action1.AddParameter(new EdmOperationParameter(action1, "Street", MetadataUtils.GetPrimitiveTypeReference(typeof(string))));
                action1.AddParameter(new EdmOperationParameter(action1, "City", MetadataUtils.GetPrimitiveTypeReference(typeof(string))));
                action1.AddParameter(new EdmOperationParameter(action1, "PostalCode", MetadataUtils.GetPrimitiveTypeReference(typeof(string))));
                
                metadata.AddActionImport("ChangeAddress", action1, null /*entitySet*/);
                
                // Unbound action with no parameters
                var getRecentCustomersAction = metadata.AddAction("GetRecentCustomers", null /*boundType*/, new EdmCollectionTypeReference(new EdmCollectionType(orderType.ToTypeReference())), false /*isbound*/, null /*entitySetPathExpression*/);
                metadata.AddActionImport("GetRecentCustomers", getRecentCustomersAction, orderset);

                //Adding order details navigation property to order.
                var orderDetailNavigation = metadata.AddResourceSetReferenceProperty(orderType, "OrderDetails", orderdetailsSet, null);

                //Adding orders navigation to Customer.
                var ordersNavigation = metadata.AddResourceSetReferenceProperty(customerType, "Orders", orderset, null);
                ((EdmEntitySet)customerset).AddNavigationTarget(ordersNavigation, orderset);

                //Adding parent navigation to person
                metadata.AddResourceSetReferenceProperty(personType, "Parent", null, personType);

                //Since the people set can contain a customer we need to include the target for that navigation in the people set.
                ((EdmEntitySet)peopleset).AddNavigationTarget(ordersNavigation, orderset);

                //Since the OrderSet can contain a OrderDetail we need to include the target for that navigation in the order set.
                ((EdmEntitySet)orderset).AddNavigationTarget(orderDetailNavigation, orderdetailsSet);

                //Since the OrderDetailSet can contain a AssociatedOrder we need to include the target for that navigation in the orderdetail set.
                ((EdmEntitySet)orderdetailsSet).AddNavigationTarget(associatedOrderNavigation, orderset);

                //Since the OrderDetailSet can contain a ProductOrdered we need to include the target for that navigation in the orderdetail set.
                ((EdmEntitySet)orderdetailsSet).AddNavigationTarget(productOrderedNavigation, productset);

                ((EdmSingleton)specialOrder).AddNavigationTarget(orderDetailNavigation, orderdetailsSet);
                ((EdmSingleton)specialPerson).AddNavigationTarget(ordersNavigation, orderset);

                this.model = metadata;
            }

            return this.model;
        }
 /// <summary>
 /// Adds a <paramref name="property"/> to <paramref name="metadata"/>
 /// under type <paramref name="structuredType"/>
 /// </summary>
 /// <param name="metadata">Metadata document to be added to</param>
 /// <param name="property">Property to add</param>
 /// <param name="structuredType">Structured type to add property to</param>
 private static void AddProperty(ConstructableMetadata metadata, EdmProperty property, IEdmStructuredType structuredType)
 {
     if (property.BuiltInTypeKind == BuiltInTypeKind.EdmProperty)
     {
         AddPrimitiveProperty(metadata, DataTypeToSystemType((PrimitiveType)property.TypeUsage.EdmType, IsNullable(property.TypeUsage)), property, structuredType);
     }
     else if (property.BuiltInTypeKind == BuiltInTypeKind.ComplexType)
     {
         metadata.AddComplexProperty(structuredType, property.Name, metadata.FindType(property.TypeUsage.EdmType.FullName) as IEdmComplexType);
     }
 }
Esempio n. 7
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(ConstructableMetadata model, EdmStructuredType owningType, IEnumerable<ODataProperty> properties)
        {
            if (properties == null)
            {
                return;
            }

            EdmEntityType owningEntityType = owningType as EdmEntityType;
            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 EdmEntityType,
                        "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)
                {
                    ProcessComplexProperty(model, owningType, complexValue, isOpenProperty);
                }
                else
                {
                    bool isKeyProperty = false;
                    if (propertyMetadataAnnotation != null)
                    {
                        isKeyProperty = (propertyMetadataAnnotation.Kind & ODataPropertyKind.Key) == ODataPropertyKind.Key;
                        bool isETagProperty = (propertyMetadataAnnotation.Kind & ODataPropertyKind.ETag) == ODataPropertyKind.ETag;

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

                    if (owningEntityType != null && isOpenProperty)
                    {
                        //TODO: figure out how to set entity type to open after creation.
                    }
                    else
                    {
                        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.");
                            var keyPropertyType = GetPrimitiveTypeReference(propertyValue.GetType());
                            var keyProperty = owningEntityType.AddStructuralProperty(property.Name, keyPropertyType);
                            owningEntityType.AddKeys(keyProperty);
                        }
                        else
                        {
                            if (propertyValue is ODataCollectionValue)
                            {
                                ProcessCollectionProperty(model, owningType, propertyValue, owningEntityType, property);
                            }
                            else
                            {
                                Type propertyType = propertyValue == null ? typeof(string) : propertyValue.GetType();
                                owningType.AddProperty(new EdmStructuralProperty(owningType, property.Name, GetPrimitiveTypeReference(propertyType)));
                            }
                        }
                    }
                }
            }
        }
Esempio n. 8
0
 /// <summary>
 /// Creates metadata for an entity derived from the data.
 /// </summary>
 /// <param name="model">The created model.</param>
 /// <param name="namespaceName">The namespace name for the new type(s).</param>
 /// <param name="entry">The entry to create the metadata for.</param>
 /// <returns>The entity type of the created entity.</returns>
 public static IEdmEntityType CreateEntityMetadata(string namespaceName, ODataEntry entry, out IEdmModel model)
 {
     var metadata = new ConstructableMetadata("DefaultContainer", namespaceName);
     
     ExceptionUtilities.Assert(entry.TypeName.StartsWith(namespaceName + "."), "The type name must start with Namespace.");
     
     EdmEntityType entityType = metadata.AddEntityType(entry.TypeName, null, null, false) as EdmEntityType;
     
     CreateMetadataProperties(metadata, entityType, entry.Properties);
     model = metadata;
     return entityType;
 }
Esempio n. 9
0
        private static void ProcessComplexProperty(ConstructableMetadata model, EdmStructuredType owningType, ODataComplexValue complexValue, bool isOpenProperty)
        {
            string namespaceName = "";
            var schematype = owningType as IEdmSchemaType;
            if (schematype != null)
            {
                namespaceName = schematype.Namespace;
            }

            ExceptionUtilities.Assert(complexValue.TypeName.StartsWith(namespaceName + "."), "The type name must start with the same namespace as its owning type.");

            EdmComplexType complexType = model.FindType(complexValue.TypeName) as EdmComplexType;
            if (complexType == null)
            {
                string complexTypeLocalName = complexValue.GetUnqualifiedTypeName(namespaceName);
                complexType = model.AddComplexType(complexTypeLocalName, null, null, false) as EdmComplexType;
                CreateMetadataProperties(model, complexType, complexValue.Properties);
            }

            if (isOpenProperty)
            {
                //TODO: Find way to set parent type to open.
            }
            else
            {
                ExceptionUtilities.CheckObjectNotNull(complexType, "Complex type cannot be null");
                owningType.AddProperty(new EdmStructuralProperty(owningType, complexType.Name, complexType.ToTypeReference()));
            }
        }
Esempio n. 10
0
        private static IEdmCollectionType GetCollectionType(ConstructableMetadata model, IEdmPrimitiveTypeReference primitiveItemType, string itemTypeName)
        {
            if (primitiveItemType != null)
            {
                return new EdmCollectionType(primitiveItemType);
            }
            
            IEdmType itemType = model.FindDeclaredType(itemTypeName);
            IEdmComplexType complexItemType = itemType as IEdmComplexType;
            if (complexItemType != null)
            {
                return new EdmCollectionType(complexItemType.ToTypeReference());
            }

            return null;
        }
Esempio n. 11
0
        private static void ProcessCollectionProperty(ConstructableMetadata model, EdmStructuredType owningType, object propertyValue, EdmEntityType owningEntityType, ODataProperty property)
        {
            string itemTypeName = EdmModelUtils.GetCollectionItemTypeName(((ODataCollectionValue)propertyValue).TypeName);
            IEdmPrimitiveTypeReference primitiveItemType = MetadataUtils.GetPrimitiveTypeReference(itemTypeName);
            IEdmCollectionType collectionType = GetCollectionType(model, primitiveItemType, itemTypeName);

            ExceptionUtilities.Assert(collectionType != null, "Could not resolve item type.");
            owningType.AddProperty(new EdmStructuralProperty(owningType, property.Name, collectionType.ToTypeReference()));
        }