예제 #1
0
        /// <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);
        }
예제 #2
0
        public void EntityType_reference_extensions()
        {
            IEdmModel      edmModel          = this.GetEdmModel();
            IEdmEntityType derivedEntityType = edmModel.SchemaElements.OfType <IEdmEntityType>().First(c => c.BaseType != null);
            IEdmEntityType baseEntityType    = derivedEntityType.BaseEntityType();

            Assert.IsNotNull(baseEntityType, "Base entity type should not be null!");

            IEdmEntityTypeReference derivedEntityTypeRef = (IEdmEntityTypeReference)derivedEntityType.ToTypeReference();

            Assert.AreEqual(baseEntityType, derivedEntityTypeRef.BaseEntityType(), "EntityTypeReference.BaseEntityType()");
            Assert.AreEqual(baseEntityType, derivedEntityTypeRef.BaseType(), "EntityTypeReference.BaseType()");

            Assert.AreEqual(derivedEntityType.IsAbstract, derivedEntityTypeRef.IsAbstract(), "StructuralTypeReference.IsAbstract()");
            Assert.AreEqual(derivedEntityType.IsOpen, derivedEntityTypeRef.IsOpen(), "StructuralTypeReference.IsOpen()");

            Assert.AreEqual(derivedEntityType.DeclaredStructuralProperties().Count(), derivedEntityTypeRef.DeclaredStructuralProperties().Count(), "StructuralTypeReference.DeclaredStructuralProperties()");
            Assert.AreEqual(derivedEntityType.StructuralProperties().Count(), derivedEntityTypeRef.StructuralProperties().Count(), "StructuralTypeReference.StructuralProperties()");

            Assert.AreEqual(derivedEntityType.DeclaredNavigationProperties().Count(), derivedEntityTypeRef.DeclaredNavigationProperties().Count(), "EntityTypeReference.DeclaredNavigationProperties()");
            Assert.AreEqual(derivedEntityType.NavigationProperties().Count(), derivedEntityTypeRef.NavigationProperties().Count(), "EntityTypeReference.NavigationProperties()");

            IEdmNavigationProperty result = derivedEntityTypeRef.FindNavigationProperty("_Not_Exist_");

            Assert.IsNull(result, "Should not find Navigation Property {0}", "_Not_Exist_");

            var navigation = derivedEntityType.NavigationProperties().First();

            result = derivedEntityTypeRef.FindNavigationProperty(navigation.Name);
            Assert.AreEqual(navigation, result, "FindNavigationProperty({0})", navigation.Name);
        }
 /// <summary>
 /// Creates a new instance of the type annotation for an entity value.
 /// </summary>
 /// <param name="navigationSource">The navigation source the entity belongs to (required).</param>
 /// <param name="entityType">The entity type of the entity value if not the base type of the entity set (optional).</param>
 public ODataTypeAnnotation(IEdmNavigationSource navigationSource, IEdmEntityType entityType)
 {
     ExceptionUtils.CheckArgumentNotNull(navigationSource, "navigation source");
     ExceptionUtils.CheckArgumentNotNull(entityType, "entityType");
     this.navigationSource = navigationSource;
     this.type             = entityType.ToTypeReference(/*isNullable*/ true);
 }
예제 #4
0
 /// <summary>
 /// Creates a new instance of the type annotation for an entity value.
 /// </summary>
 /// <param name="entitySet">The entity set the entity belongs to (required).</param>
 /// <param name="entityType">The entity type of the entity value if not the base type of the entity set (optional).</param>
 public ODataTypeAnnotation(IEdmEntitySet entitySet, IEdmEntityType entityType)
 {
     ExceptionUtils.CheckArgumentNotNull(entitySet, "entitySet");
     ExceptionUtils.CheckArgumentNotNull(entityType, "entityType");
     this.entitySet = entitySet;
     this.type      = entityType.ToTypeReference(/*isNullable*/ true);
 }
예제 #5
0
        /// <summary>Helper method to add a reference 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="targetEntitySet">The entity set the resource reference property points to.</param>
        /// <param name="targetEntityType">The entity type the entity set reference property points to.</param>
        /// <param name="resourceSetReference">true if the property should be a entity set reference, false if it should be an entity reference.</param>
        private IEdmNavigationProperty AddReferenceProperty(IEdmEntityType entityType, string name, IEdmEntitySet targetEntitySet, IEdmEntityType targetEntityType, bool resourceSetReference, bool containsTarget)
        {
            targetEntityType = targetEntityType ?? targetEntitySet.EntityType();

            IEdmTypeReference navPropertyTypeReference = resourceSetReference
                ? new EdmCollectionType(targetEntityType.ToTypeReference(true)).ToTypeReference(true)
                : targetEntityType.ToTypeReference(true);

            IEdmNavigationProperty navigationProperty = AddNavigationProperty(
                entityType,
                name,
                EdmOnDeleteAction.None,
                navPropertyTypeReference,
                containsTarget);

            return(navigationProperty);
        }
예제 #6
0
        public void EntityType_reference_findNavigation_with_null()
        {
            IEdmModel               edmModel             = this.GetEdmModel();
            IEdmEntityType          derivedEntityType    = edmModel.SchemaElements.OfType <IEdmEntityType>().First(c => c.BaseType != null);
            IEdmEntityTypeReference derivedEntityTypeRef = (IEdmEntityTypeReference)derivedEntityType.ToTypeReference();

            this.VerifyThrowsException(typeof(System.ArgumentNullException), () => derivedEntityTypeRef.FindNavigationProperty(null));
        }
예제 #7
0
        /// <summary>
        /// Converts an entity data type to a entity type.
        /// </summary>
        /// <param name="entity">The entity data type to convert.</param>
        /// <returns>The corresponding entity type.</returns>
        private static IEdmEntityTypeReference GetEntityType(IEdmModel model, EntityDataType entityDataType)
        {
            Debug.Assert(entityDataType != null, "entityDataType != null");

            IEdmSchemaType edmType = model.FindType(entityDataType.Definition.FullName);

            ExceptionUtilities.Assert(
                edmType != null,
                "The expected entity type '{0}' was not found in the entity model for this test.",
                entityDataType.Definition.FullName);

            IEdmEntityType entityType = edmType as IEdmEntityType;

            ExceptionUtilities.Assert(
                entityType != null,
                "The expected entity type '{0}' is not defined as entity type in the test's metadata.",
                entityDataType.Definition.FullName);
            return((IEdmEntityTypeReference)entityType.ToTypeReference(entityDataType.IsNullable));
        }
예제 #8
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);
        }
예제 #9
0
        protected override void EndEntry(ODataEntry entry)
        {
            Debug.Assert(
                this.ParentNavigationLink == null || !this.ParentNavigationLink.IsCollection.Value,
                "We should have already verified that the IsCollection matches the actual content of the link (feed/entry).");

            if (entry == null)
            {
                Debug.Assert(this.ParentNavigationLink != null, "When entry == null, it has to be an expanded single entry navigation.");

                // this is a null expanded single entry and it is null, an empty <m:inline /> will be written.
                this.CheckAndWriteParentNavigationLinkEndForInlineElement();
                return;
            }

            IEdmEntityType entryType = this.EntryEntityType;

            // Initialize the property value cache and cache the entry properties.
            EntryPropertiesValueCache propertyValueCache = new EntryPropertiesValueCache(entry);

            // NOTE: when writing, we assume the model has been validated already and thus pass int.MaxValue for the maxMappingCount.
            ODataEntityPropertyMappingCache epmCache = this.atomOutputContext.Model.EnsureEpmCache(entryType, /*maxMappingCount*/ int.MaxValue);

            // Populate the property value cache based on the EPM source tree information.
            // We do this since we need to write custom EPM after the properties below and don't
            // want to cache all properties just for the case that they are used in a custom EPM.
            if (epmCache != null)
            {
                EpmWriterUtils.CacheEpmProperties(propertyValueCache, epmCache.EpmSourceTree);
            }

            // Get the projected properties annotation
            ProjectedPropertiesAnnotation projectedProperties = entry.GetAnnotation <ProjectedPropertiesAnnotation>();

            AtomEntryScope    currentEntryScope = this.CurrentEntryScope;
            AtomEntryMetadata entryMetadata     = entry.Atom();

            if (!currentEntryScope.IsElementWritten(AtomElement.Id))
            {
                // NOTE: We write even null id, in that case we generate an empty atom:id element.
                this.atomEntryAndFeedSerializer.WriteEntryId(entry.Id);
            }

            Uri editLink = entry.EditLink;

            if (editLink != null && !currentEntryScope.IsElementWritten(AtomElement.EditLink))
            {
                this.atomEntryAndFeedSerializer.WriteEntryEditLink(editLink, entryMetadata);
            }

            Uri readLink = entry.ReadLink;

            if (readLink != null && !currentEntryScope.IsElementWritten(AtomElement.ReadLink))
            {
                this.atomEntryAndFeedSerializer.WriteEntryReadLink(readLink, entryMetadata);
            }

            // write entry metadata including syndication EPM
            AtomEntryMetadata epmEntryMetadata = null;

            if (epmCache != null)
            {
                ODataVersionChecker.CheckEntityPropertyMapping(this.atomOutputContext.Version, entryType, this.atomOutputContext.Model);

                epmEntryMetadata = EpmSyndicationWriter.WriteEntryEpm(
                    epmCache.EpmTargetTree,
                    propertyValueCache,
                    entryType.ToTypeReference().AsEntity(),
                    this.atomOutputContext);
            }

            this.atomEntryAndFeedSerializer.WriteEntryMetadata(entryMetadata, epmEntryMetadata, this.updatedTime);

            // stream properties
            IEnumerable <ODataProperty> streamProperties = propertyValueCache.EntryStreamProperties;

            if (streamProperties != null)
            {
                foreach (ODataProperty streamProperty in streamProperties)
                {
                    this.atomEntryAndFeedSerializer.WriteStreamProperty(
                        streamProperty,
                        entryType,
                        this.DuplicatePropertyNamesChecker,
                        projectedProperties);
                }
            }

            // association links
            IEnumerable <ODataAssociationLink> associationLinks = entry.AssociationLinks;

            if (associationLinks != null)
            {
                foreach (ODataAssociationLink associationLink in associationLinks)
                {
                    this.atomEntryAndFeedSerializer.WriteAssociationLink(
                        associationLink,
                        entryType,
                        this.DuplicatePropertyNamesChecker,
                        projectedProperties);
                }
            }

            // actions
            IEnumerable <ODataAction> actions = entry.Actions;

            if (actions != null)
            {
                foreach (ODataAction action in actions)
                {
                    ValidationUtils.ValidateOperationNotNull(action, true);
                    this.atomEntryAndFeedSerializer.WriteOperation(action);
                }
            }

            // functions
            IEnumerable <ODataFunction> functions = entry.Functions;

            if (functions != null)
            {
                foreach (ODataFunction function in functions)
                {
                    ValidationUtils.ValidateOperationNotNull(function, false);
                    this.atomEntryAndFeedSerializer.WriteOperation(function);
                }
            }

            // write the content
            this.WriteEntryContent(
                entry,
                entryType,
                propertyValueCache,
                epmCache == null ? null : epmCache.EpmSourceTree.Root,
                projectedProperties);

            // write custom EPM
            if (epmCache != null)
            {
                EpmCustomWriter.WriteEntryEpm(
                    this.atomOutputContext.XmlWriter,
                    epmCache.EpmTargetTree,
                    propertyValueCache,
                    entryType.ToTypeReference().AsEntity(),
                    this.atomOutputContext);
            }

            // </entry>
            this.atomOutputContext.XmlWriter.WriteEndElement();

            this.EndEntryXmlCustomization(entry);

            this.CheckAndWriteParentNavigationLinkEndForInlineElement();
        }
예제 #10
0
        public void ODataEntryEdmValueTest()
        {
            IEdmModel model = Test.OData.Utils.Metadata.TestModels.BuildEdmValueModel();

            ODataEntry[] entries = new ODataEntry[]
            {
                // Entry with a single primitive property
                new ODataEntry {
                    TypeName = "TestModel.SinglePrimitivePropertyEntityType", Properties = singlePrimitiveProperty
                },

                // Entry with a single null property
                new ODataEntry {
                    TypeName = "TestModel.SinglePrimitivePropertyEntityType", Properties = singleNullProperty
                },

                // Entry with all primitive typed properties
                new ODataEntry {
                    TypeName = "TestModel.AllPrimitivePropertiesEntityType", Properties = allPrimitiveProperties
                },

                // Entry with complex property
                new ODataEntry {
                    TypeName = "TestModel.SingleComplexPropertyEntityType", Properties = complexProperty
                },

                // Entry with nested complex property
                new ODataEntry {
                    TypeName = "TestModel.SingleComplexPropertyEntityType", Properties = nestedComplexProperty
                },

                // Entry with primitive collection property
                new ODataEntry {
                    TypeName = "TestModel.SinglePrimitiveCollectionPropertyEntityType", Properties = primitiveCollectionProperty
                },

                // Entry with complex collection property
                new ODataEntry {
                    TypeName = "TestModel.SingleComplexCollectionPropertyEntityType", Properties = complexCollectionProperty
                },

                // Entry with different kinds of properties
                new ODataEntry {
                    TypeName = "TestModel.DifferentPropertyKindsEntityType", Properties = differentPropertyKinds
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                entries,
                new bool[] { true, false },
                (entry, includeTypeReferences) =>
            {
                IEdmEntityTypeReference typeReference = null;
                IEdmEntitySet entitySet = null;
                if (includeTypeReferences)
                {
                    IEdmEntityType schemaType = (IEdmEntityType)model.FindType(entry.TypeName);
                    this.Assert.IsNotNull(schemaType, "Expected to find type in the model.");
                    typeReference = (IEdmEntityTypeReference)schemaType.ToTypeReference(/*nullable*/ false);

                    IEdmEntityContainer container = model.EntityContainer;
                    if (container != null)
                    {
                        entitySet = container.FindEntitySet(schemaType.Name + "Set");
                    }
                }

                IEdmValue entryEdmValue = ODataEdmValueUtils.CreateStructuredEdmValue(entry, entitySet, typeReference);
                ODataEdmValueUtils.CompareValue(entryEdmValue, entry, this.Assert);
            });
        }
예제 #11
0
        /// <summary>Helper method to add a reference 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="targetEntitySet">The entity set the resource reference property points to.</param>
        /// <param name="targetEntityType">The entity type the entity set reference property points to.</param>
        /// <param name="resourceSetReference">true if the property should be a entity set reference, false if it should be an entity reference.</param>
        private IEdmNavigationProperty AddReferenceProperty(IEdmEntityType entityType, string name, IEdmEntitySet targetEntitySet, IEdmEntityType targetEntityType, bool resourceSetReference, bool containsTarget)
        {
            targetEntityType = targetEntityType ?? targetEntitySet.EntityType();

            IEdmTypeReference navPropertyTypeReference = resourceSetReference
                ? new EdmCollectionType(targetEntityType.ToTypeReference(true)).ToTypeReference(true)
                : targetEntityType.ToTypeReference(true);

            IEdmNavigationProperty navigationProperty = AddNavigationProperty(
                entityType,
                name,
                EdmOnDeleteAction.None,
                navPropertyTypeReference,
                containsTarget);

            return navigationProperty;
        }
예제 #12
0
        /// <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;
        }
예제 #13
0
 protected override void EndEntry(ODataEntry entry)
 {
     if (entry == null)
     {
         this.CheckAndWriteParentNavigationLinkEndForInlineElement();
     }
     else
     {
         IEdmEntityType                  entryEntityType    = base.EntryEntityType;
         EntryPropertiesValueCache       propertyValueCache = new EntryPropertiesValueCache(entry);
         ODataEntityPropertyMappingCache cache2             = this.atomOutputContext.Model.EnsureEpmCache(entryEntityType, 0x7fffffff);
         if (cache2 != null)
         {
             EpmWriterUtils.CacheEpmProperties(propertyValueCache, cache2.EpmSourceTree);
         }
         ProjectedPropertiesAnnotation projectedProperties = entry.GetAnnotation <ProjectedPropertiesAnnotation>();
         AtomEntryScope    currentEntryScope = this.CurrentEntryScope;
         AtomEntryMetadata entryMetadata     = entry.Atom();
         if (!currentEntryScope.IsElementWritten(AtomElement.Id))
         {
             this.atomEntryAndFeedSerializer.WriteEntryId(entry.Id);
         }
         Uri editLink = entry.EditLink;
         if ((editLink != null) && !currentEntryScope.IsElementWritten(AtomElement.EditLink))
         {
             this.atomEntryAndFeedSerializer.WriteEntryEditLink(editLink, entryMetadata);
         }
         Uri readLink = entry.ReadLink;
         if ((readLink != null) && !currentEntryScope.IsElementWritten(AtomElement.ReadLink))
         {
             this.atomEntryAndFeedSerializer.WriteEntryReadLink(readLink, entryMetadata);
         }
         AtomEntryMetadata epmEntryMetadata = null;
         if (cache2 != null)
         {
             ODataVersionChecker.CheckEntityPropertyMapping(this.atomOutputContext.Version, entryEntityType, this.atomOutputContext.Model);
             epmEntryMetadata = EpmSyndicationWriter.WriteEntryEpm(cache2.EpmTargetTree, propertyValueCache, entryEntityType.ToTypeReference().AsEntity(), this.atomOutputContext);
         }
         this.atomEntryAndFeedSerializer.WriteEntryMetadata(entryMetadata, epmEntryMetadata, this.updatedTime);
         IEnumerable <ODataProperty> entryStreamProperties = propertyValueCache.EntryStreamProperties;
         if (entryStreamProperties != null)
         {
             foreach (ODataProperty property in entryStreamProperties)
             {
                 this.atomEntryAndFeedSerializer.WriteStreamProperty(property, entryEntityType, base.DuplicatePropertyNamesChecker, projectedProperties);
             }
         }
         IEnumerable <ODataAssociationLink> associationLinks = entry.AssociationLinks;
         if (associationLinks != null)
         {
             foreach (ODataAssociationLink link in associationLinks)
             {
                 this.atomEntryAndFeedSerializer.WriteAssociationLink(link, entryEntityType, base.DuplicatePropertyNamesChecker, projectedProperties);
             }
         }
         IEnumerable <ODataAction> actions = entry.Actions;
         if (actions != null)
         {
             foreach (ODataAction action in actions)
             {
                 ValidationUtils.ValidateOperationNotNull(action, true);
                 this.atomEntryAndFeedSerializer.WriteOperation(action);
             }
         }
         IEnumerable <ODataFunction> functions = entry.Functions;
         if (functions != null)
         {
             foreach (ODataFunction function in functions)
             {
                 ValidationUtils.ValidateOperationNotNull(function, false);
                 this.atomEntryAndFeedSerializer.WriteOperation(function);
             }
         }
         this.WriteEntryContent(entry, entryEntityType, propertyValueCache, (cache2 == null) ? null : cache2.EpmSourceTree.Root, projectedProperties);
         if (cache2 != null)
         {
             EpmCustomWriter.WriteEntryEpm(this.atomOutputContext.XmlWriter, cache2.EpmTargetTree, propertyValueCache, entryEntityType.ToTypeReference().AsEntity(), this.atomOutputContext);
         }
         this.atomOutputContext.XmlWriter.WriteEndElement();
         this.EndEntryXmlCustomization(entry);
         this.CheckAndWriteParentNavigationLinkEndForInlineElement();
     }
 }
예제 #14
0
        /// <summary>
        /// Resolves the specified entity model schema type and returns the Edm model type for it.
        /// </summary>
        /// <param name="model">The model to get the type from.</param>
        /// <param name="schemaType">The entity model schema type to resolve.</param>
        /// <returns>The resolved type for the specified <paramref name="schemaType"/>.</returns>
        public static IEdmTypeReference ResolveEntityModelSchemaType(IEdmModel model, DataType schemaType)
        {
            if (schemaType == null)
            {
                return(null);
            }

            PrimitiveDataType primitiveDataType = schemaType as PrimitiveDataType;

            if (primitiveDataType != null)
            {
                return(GetPrimitiveTypeReference(primitiveDataType));
            }

            if (model == null)
            {
                return(null);
            }

            EntityDataType entityDataType = schemaType as EntityDataType;

            if (entityDataType != null)
            {
                IEdmNamedElement edmType = model.FindType(entityDataType.Definition.FullName);
                ExceptionUtilities.Assert(
                    edmType != null,
                    "The expected entity type '{0}' was not found in the entity model for this test.",
                    entityDataType.Definition.FullName);

                IEdmEntityType entityType = edmType as IEdmEntityType;
                ExceptionUtilities.Assert(
                    entityType != null,
                    "The expected entity type '{0}' is not defined as entity type in the test's metadata.",
                    entityDataType.Definition.FullName);
                return(entityType.ToTypeReference());
            }

            ComplexDataType complexDataType = schemaType as ComplexDataType;

            if (complexDataType != null)
            {
                return(GetComplexType(model, complexDataType));
            }

            CollectionDataType collectionDataType = schemaType as CollectionDataType;

            if (collectionDataType != null)
            {
                DataType          collectionElementType = collectionDataType.ElementDataType;
                PrimitiveDataType primitiveElementType  = collectionElementType as PrimitiveDataType;
                if (primitiveElementType != null)
                {
                    IEdmPrimitiveTypeReference primitiveElementTypeReference = GetPrimitiveTypeReference(primitiveElementType);
                    return(primitiveElementTypeReference.ToCollectionTypeReference());
                }

                ComplexDataType complexElementType = collectionElementType as ComplexDataType;
                if (complexElementType != null)
                {
                    IEdmComplexTypeReference complexElementTypeReference = GetComplexType(model, complexElementType);
                    return(complexElementTypeReference.ToCollectionTypeReference());
                }

                EntityDataType entityElementType = collectionElementType as EntityDataType;
                if (entityElementType != null)
                {
                    IEdmEntityTypeReference entityElementTypeReference = GetEntityType(model, entityElementType);
                    return(entityElementTypeReference.ToCollectionTypeReference());
                }

                throw new NotSupportedException("Collection types only support primitive, complex, and entity element types.");
            }

            StreamDataType streamType = schemaType as StreamDataType;

            if (streamType != null)
            {
                Type systemType = streamType.GetFacet <PrimitiveClrTypeFacet>().Value;
                ExceptionUtilities.Assert(systemType == typeof(Stream), "Expected the system type 'System.IO.Stream' for a stream reference property.");
                return(MetadataUtils.GetPrimitiveTypeReference(systemType));
            }

            throw new NotImplementedException("Unrecognized schema type " + schemaType.GetType().Name + ".");
        }
예제 #15
0
 /// <summary>
 /// Creates a new instance of the type annotation for an entity value.
 /// </summary>
 /// <param name="navigationSource">The navigation source the entity belongs to (required).</param>
 /// <param name="entityType">The entity type of the entity value if not the base type of the entity set (optional).</param>
 public ODataTypeAnnotation(IEdmNavigationSource navigationSource, IEdmEntityType entityType)
 {
     ExceptionUtils.CheckArgumentNotNull(entityType, "entityType");
     this.navigationSource = navigationSource;
     this.type = entityType.ToTypeReference(/*isNullable*/ true);
 }