예제 #1
0
 public Task<IEdmModel> GetModelAsync(ModelContext context, CancellationToken cancellationToken)
 {
     var model = new EdmModel();
     var dummyType = new EdmEntityType("NS", "Dummy");
     model.AddElement(dummyType);
     var container = new EdmEntityContainer("NS", "DefaultContainer");
     container.AddEntitySet("Test", dummyType);
     model.AddElement(container);
     return Task.FromResult((IEdmModel) model);
 }
예제 #2
0
        public WriterTypeNameEndToEndTests()
        {
            var model       = new EdmModel();
            var type        = new EdmEntityType("TestModel", "TestEntity", /* baseType */ null, /* isAbstract */ false, /* isOpen */ true);
            var keyProperty = type.AddStructuralProperty("DeclaredInt16", EdmPrimitiveTypeKind.Int16);

            type.AddKeys(new[] { keyProperty });

            // Note: DerivedPrimitive is declared as a Geography, but its value below will be set to GeographyPoint, which is derived from Geography.
            type.AddStructuralProperty("DerivedPrimitive", EdmPrimitiveTypeKind.Geography);
            var container = new EdmEntityContainer("TestModel", "Container");
            var set       = container.AddEntitySet("Set", type);

            model.AddElement(type);
            model.AddElement(container);

            var writerStream = new MemoryStream();

            this.settings = new ODataMessageWriterSettings();
            this.settings.SetServiceDocumentUri(ServiceDocumentUri);

            // Make the message writer and entry writer lazy so that individual tests can tweak the settings before the message writer is created.
            this.messageWriter = new Lazy <ODataMessageWriter>(() =>
                                                               new ODataMessageWriter(
                                                                   (IODataResponseMessage) new InMemoryMessage {
                Stream = writerStream
            },
                                                                   this.settings,
                                                                   model));

            var entryWriter = new Lazy <ODataWriter>(() => this.messageWriter.Value.CreateODataEntryWriter(set, type));

            var valueWithAnnotation = new ODataPrimitiveValue(45);

            valueWithAnnotation.SetAnnotation(new SerializationTypeNameAnnotation {
                TypeName = "TypeNameFromSTNA"
            });

            var propertiesToWrite = new List <ODataProperty>
            {
                new ODataProperty
                {
                    Name = "DeclaredInt16", Value = (Int16)42
                },
                new ODataProperty
                {
                    Name = "UndeclaredDecimal", Value = (Decimal)4.5
                },
                new ODataProperty
                {
                    // Note: value is more derived than the declared type.
                    Name = "DerivedPrimitive", Value = Microsoft.Spatial.GeographyPoint.Create(42, 45)
                },
                new ODataProperty()
                {
                    Name = "PropertyWithSTNA", Value = valueWithAnnotation
                }
            };

            this.writerOutput = new Lazy <string>(() =>
            {
                entryWriter.Value.WriteStart(new ODataEntry {
                    Properties = propertiesToWrite
                });
                entryWriter.Value.WriteEnd();
                entryWriter.Value.Flush();
                writerStream.Seek(0, SeekOrigin.Begin);
                return(new StreamReader(writerStream).ReadToEnd());
            });
        }
예제 #3
0
        private static IEdmModel GetEdmModel()
        {
            EdmModel model = new EdmModel();

            IEdmTypeReference returnType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Boolean, isNullable: false);
            IEdmTypeReference stringType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.String, isNullable: false);
            IEdmTypeReference intType    = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Int32, isNullable: false);

            // Entity
            EdmEntityType entity = new EdmEntityType("NS", "Entity", null, true, false);

            model.AddElement(entity);

            // Customer
            EdmEntityType customer = new EdmEntityType("NS", "Customer", entity);

            customer.AddKeys(customer.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
            model.AddElement(customer);

            // VipCustomer
            EdmEntityType vipCustomer = new EdmEntityType("NS", "VipCustomer", customer);

            model.AddElement(vipCustomer);

            // functions bound to single
            EdmFunction isBaseUpgraded = new EdmFunction("NS", "IsBaseUpgraded", returnType, true, entitySetPathExpression: null, isComposable: false);

            isBaseUpgraded.AddParameter("entity", new EdmEntityTypeReference(entity, false));
            model.AddElement(isBaseUpgraded);

            EdmFunction isUpgraded = new EdmFunction("NS", "IsUpgraded", returnType, true, entitySetPathExpression: null, isComposable: false);

            isUpgraded.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(isUpgraded);

            EdmFunction isVipUpgraded = new EdmFunction("NS", "IsVipUpgraded", returnType, true, entitySetPathExpression: null, isComposable: false);

            isVipUpgraded.AddParameter("entity", new EdmEntityTypeReference(vipCustomer, false));
            isVipUpgraded.AddParameter("param", stringType);
            model.AddElement(isVipUpgraded);

            // functions bound to collection
            EdmFunction isBaseAllUpgraded = new EdmFunction("NS", "IsBaseAllUpgraded", returnType, true, entitySetPathExpression: null, isComposable: false);

            isBaseAllUpgraded.AddParameter("entityset", new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(entity, false))));
            isBaseAllUpgraded.AddParameter("param", intType);
            model.AddElement(isBaseAllUpgraded);

            EdmFunction isAllUpgraded = new EdmFunction("NS", "IsAllCustomersUpgraded", returnType, true, entitySetPathExpression: null, isComposable: false);

            isAllUpgraded.AddParameter("entityset", new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(customer, false))));
            isAllUpgraded.AddParameter("param", intType);
            model.AddElement(isAllUpgraded);

            EdmFunction isVipAllUpgraded = new EdmFunction("NS", "IsVipAllUpgraded", returnType, true, entitySetPathExpression: null, isComposable: false);

            isVipAllUpgraded.AddParameter("entityset", new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(vipCustomer, false))));
            isVipAllUpgraded.AddParameter("param", intType);
            model.AddElement(isVipAllUpgraded);

            // overloads
            EdmFunction upgradeAll1 = new EdmFunction("NS", "UpgradedAll", returnType, true, entitySetPathExpression: null, isComposable: false);

            upgradeAll1.AddParameter("entityset", new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(customer, false))));
            upgradeAll1.AddParameter("age", intType);
            upgradeAll1.AddParameter("name", stringType);
            model.AddElement(upgradeAll1);

            EdmFunction upgradeAll2 = new EdmFunction("NS", "UpgradedAll", returnType, true, entitySetPathExpression: null, isComposable: false);

            upgradeAll2.AddParameter("entityset", new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(customer, false))));
            upgradeAll2.AddParameter("age", intType);
            upgradeAll2.AddParameter("name", stringType);
            upgradeAll2.AddParameter("gender", stringType);
            model.AddElement(upgradeAll2);

            EdmFunction upgradeAll3 = new EdmFunction("NS", "UpgradedAll", returnType, true, entitySetPathExpression: null, isComposable: false);

            upgradeAll3.AddParameter("entityset", new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(vipCustomer, false))));
            upgradeAll3.AddParameter("age", intType);
            upgradeAll3.AddParameter("name", stringType);
            model.AddElement(upgradeAll3);

            // function with optional parameters
            EdmFunction getSalaray = new EdmFunction("NS", "GetWholeSalary", intType, isBound: true, entitySetPathExpression: null, isComposable: false);

            getSalaray.AddParameter("entityset", new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(customer, false))));
            getSalaray.AddParameter("minSalary", intType);
            getSalaray.AddOptionalParameter("maxSalary", intType);
            getSalaray.AddOptionalParameter("aveSalary", intType, "129");
            model.AddElement(getSalaray);

            EdmEntityContainer container = new EdmEntityContainer("NS", "Default");

            container.AddEntitySet("Customers", customer);
            container.AddSingleton("Me", customer);
            model.AddElement(container);
            return(model);
        }
        public CustomersModelWithInheritance()
        {
            EdmModel model = new EdmModel();

            // Enum type simpleEnum
            EdmEnumType simpleEnum = new EdmEnumType("NS", "SimpleEnum");

            simpleEnum.AddMember(new EdmEnumMember(simpleEnum, "First", new EdmEnumMemberValue(0)));
            simpleEnum.AddMember(new EdmEnumMember(simpleEnum, "Second", new EdmEnumMemberValue(1)));
            simpleEnum.AddMember(new EdmEnumMember(simpleEnum, "Third", new EdmEnumMemberValue(2)));
            model.AddElement(simpleEnum);

            // complex type address
            EdmComplexType address = new EdmComplexType("NS", "Address");

            address.AddStructuralProperty("Street", EdmPrimitiveTypeKind.String);
            address.AddStructuralProperty("City", EdmPrimitiveTypeKind.String);
            address.AddStructuralProperty("State", EdmPrimitiveTypeKind.String);
            address.AddStructuralProperty("ZipCode", EdmPrimitiveTypeKind.String);
            address.AddStructuralProperty("Country", EdmPrimitiveTypeKind.String);
            model.AddElement(address);

            // open complex type "Account"
            EdmComplexType account = new EdmComplexType("NS", "Account", null, false, true);

            account.AddStructuralProperty("Bank", EdmPrimitiveTypeKind.String);
            account.AddStructuralProperty("CardNum", EdmPrimitiveTypeKind.Int64);
            account.AddStructuralProperty("BankAddress", new EdmComplexTypeReference(address, isNullable: true));
            model.AddElement(account);

            EdmComplexType specialAccount = new EdmComplexType("NS", "SpecialAccount", account, false, true);

            specialAccount.AddStructuralProperty("SpecialCard", EdmPrimitiveTypeKind.String);
            model.AddElement(specialAccount);

            // entity type customer
            EdmEntityType customer = new EdmEntityType("NS", "Customer");

            customer.AddKeys(customer.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            IEdmProperty customerName = customer.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);

            customer.AddStructuralProperty("SimpleEnum", simpleEnum.ToEdmTypeReference(isNullable: false));
            customer.AddStructuralProperty("Address", new EdmComplexTypeReference(address, isNullable: true));
            customer.AddStructuralProperty("Account", new EdmComplexTypeReference(account, isNullable: true));
            IEdmTypeReference primitiveTypeReference = EdmCoreModel.Instance.GetPrimitive(
                EdmPrimitiveTypeKind.String,
                isNullable: true);
            var city = customer.AddStructuralProperty(
                "City",
                primitiveTypeReference,
                defaultValue: null);

            model.AddElement(customer);

            // derived entity type special customer
            EdmEntityType specialCustomer = new EdmEntityType("NS", "SpecialCustomer", customer);

            specialCustomer.AddStructuralProperty("SpecialCustomerProperty", EdmPrimitiveTypeKind.Guid);
            specialCustomer.AddStructuralProperty("SpecialAddress", new EdmComplexTypeReference(address, isNullable: true));
            model.AddElement(specialCustomer);

            // entity type order (open entity type)
            EdmEntityType order = new EdmEntityType("NS", "Order", null, false, true);

            // EdmEntityType order = new EdmEntityType("NS", "Order");
            order.AddKeys(order.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            order.AddStructuralProperty("City", EdmPrimitiveTypeKind.String);
            order.AddStructuralProperty("Amount", EdmPrimitiveTypeKind.Int32);
            model.AddElement(order);

            // derived entity type special order
            EdmEntityType specialOrder = new EdmEntityType("NS", "SpecialOrder", order, false, true);

            specialOrder.AddStructuralProperty("SpecialOrderProperty", EdmPrimitiveTypeKind.Guid);
            model.AddElement(specialOrder);

            // test entity
            EdmEntityType testEntity = new EdmEntityType("System.Web.OData.Query.Expressions", "TestEntity");

            testEntity.AddStructuralProperty("SampleProperty", EdmPrimitiveTypeKind.Binary);
            model.AddElement(testEntity);

            // containment
            // my order
            EdmEntityType myOrder = new EdmEntityType("NS", "MyOrder");

            myOrder.AddKeys(myOrder.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            myOrder.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            model.AddElement(myOrder);

            // order line
            EdmEntityType orderLine = new EdmEntityType("NS", "OrderLine");

            orderLine.AddKeys(orderLine.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            orderLine.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            model.AddElement(orderLine);

            EdmNavigationProperty orderLinesNavProp = myOrder.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "OrderLines",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = orderLine,
                ContainsTarget     = true,
            });

            EdmNavigationProperty nonContainedOrderLinesNavProp = myOrder.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "NonContainedOrderLines",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = orderLine,
                ContainsTarget     = false,
            });

            EdmAction tag = new EdmAction("NS", "tag", returnType: null, isBound: true, entitySetPathExpression: null);

            tag.AddParameter("entity", new EdmEntityTypeReference(orderLine, false));
            model.AddElement(tag);

            // entity sets
            EdmEntityContainer container = new EdmEntityContainer("NS", "ModelWithInheritance");

            model.AddElement(container);
            EdmEntitySet customers = container.AddEntitySet("Customers", customer);
            EdmEntitySet orders    = container.AddEntitySet("Orders", order);
            EdmEntitySet myOrders  = container.AddEntitySet("MyOrders", myOrder);

            // singletons
            EdmSingleton vipCustomer = container.AddSingleton("VipCustomer", customer);
            EdmSingleton mary        = container.AddSingleton("Mary", customer);
            EdmSingleton rootOrder   = container.AddSingleton("RootOrder", order);

            // annotations
            model.SetOptimisticConcurrencyAnnotation(customers, new[] { city });

            // containment
            IEdmContainedEntitySet orderLines = (IEdmContainedEntitySet)myOrders.FindNavigationTarget(orderLinesNavProp);

            // no-containment
            IEdmNavigationSource nonContainedOrderLines = myOrders.FindNavigationTarget(nonContainedOrderLinesNavProp);

            // actions
            EdmAction upgrade = new EdmAction("NS", "upgrade", returnType: null, isBound: true, entitySetPathExpression: null);

            upgrade.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(upgrade);

            EdmAction specialUpgrade =
                new EdmAction("NS", "specialUpgrade", returnType: null, isBound: true, entitySetPathExpression: null);

            specialUpgrade.AddParameter("entity", new EdmEntityTypeReference(specialCustomer, false));
            model.AddElement(specialUpgrade);

            // actions bound to collection
            EdmAction upgradeAll = new EdmAction("NS", "UpgradeAll", returnType: null, isBound: true, entitySetPathExpression: null);

            upgradeAll.AddParameter("entityset",
                                    new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(customer, false))));
            model.AddElement(upgradeAll);

            EdmAction upgradeSpecialAll = new EdmAction("NS", "UpgradeSpecialAll", returnType: null, isBound: true, entitySetPathExpression: null);

            upgradeSpecialAll.AddParameter("entityset",
                                           new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(specialCustomer, false))));
            model.AddElement(upgradeSpecialAll);

            // functions
            IEdmTypeReference returnType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Boolean, isNullable: false);
            IEdmTypeReference stringType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.String, isNullable: false);
            IEdmTypeReference intType    = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Int32, isNullable: false);

            EdmFunction IsUpgraded = new EdmFunction(
                "NS",
                "IsUpgraded",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);

            IsUpgraded.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(IsUpgraded);

            EdmFunction orderByCityAndAmount = new EdmFunction(
                "NS",
                "OrderByCityAndAmount",
                stringType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);

            orderByCityAndAmount.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            orderByCityAndAmount.AddParameter("city", stringType);
            orderByCityAndAmount.AddParameter("amount", intType);
            model.AddElement(orderByCityAndAmount);

            EdmFunction getOrders = new EdmFunction(
                "NS",
                "GetOrders",
                EdmCoreModel.GetCollection(order.ToEdmTypeReference(false)),
                isBound: true,
                entitySetPathExpression: null,
                isComposable: true);

            getOrders.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            getOrders.AddParameter("parameter", intType);
            model.AddElement(getOrders);

            EdmFunction IsSpecialUpgraded = new EdmFunction(
                "NS",
                "IsSpecialUpgraded",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);

            IsSpecialUpgraded.AddParameter("entity", new EdmEntityTypeReference(specialCustomer, false));
            model.AddElement(IsSpecialUpgraded);

            EdmFunction getSalary = new EdmFunction(
                "NS",
                "GetSalary",
                stringType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);

            getSalary.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(getSalary);

            getSalary = new EdmFunction(
                "NS",
                "GetSalary",
                stringType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            getSalary.AddParameter("entity", new EdmEntityTypeReference(specialCustomer, false));
            model.AddElement(getSalary);

            EdmFunction IsAnyUpgraded = new EdmFunction(
                "NS",
                "IsAnyUpgraded",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            EdmCollectionType edmCollectionType = new EdmCollectionType(new EdmEntityTypeReference(customer, false));

            IsAnyUpgraded.AddParameter("entityset", new EdmCollectionTypeReference(edmCollectionType));
            model.AddElement(IsAnyUpgraded);

            EdmFunction isCustomerUpgradedWithParam = new EdmFunction(
                "NS",
                "IsUpgradedWithParam",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);

            isCustomerUpgradedWithParam.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            isCustomerUpgradedWithParam.AddParameter("city", EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.String, isNullable: false));
            model.AddElement(isCustomerUpgradedWithParam);

            EdmFunction isCustomerLocal = new EdmFunction(
                "NS",
                "IsLocal",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);

            isCustomerLocal.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(isCustomerLocal);

            EdmFunction entityFunction = new EdmFunction(
                "NS",
                "GetCustomer",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);

            entityFunction.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            entityFunction.AddParameter("customer", new EdmEntityTypeReference(customer, false));
            model.AddElement(entityFunction);

            EdmFunction getOrder = new EdmFunction(
                "NS",
                "GetOrder",
                order.ToEdmTypeReference(false),
                isBound: true,
                entitySetPathExpression: null,
                isComposable: true); // Composable

            getOrder.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            getOrder.AddParameter("orderId", intType);
            model.AddElement(getOrder);

            // functions bound to collection
            EdmFunction isAllUpgraded = new EdmFunction("NS", "IsAllUpgraded", returnType, isBound: true,
                                                        entitySetPathExpression: null, isComposable: false);

            isAllUpgraded.AddParameter("entityset",
                                       new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(customer, false))));
            isAllUpgraded.AddParameter("param", intType);
            model.AddElement(isAllUpgraded);

            EdmFunction isSpecialAllUpgraded = new EdmFunction("NS", "IsSpecialAllUpgraded", returnType, isBound: true,
                                                               entitySetPathExpression: null, isComposable: false);

            isSpecialAllUpgraded.AddParameter("entityset",
                                              new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(specialCustomer, false))));
            isSpecialAllUpgraded.AddParameter("param", intType);
            model.AddElement(isSpecialAllUpgraded);

            // navigation properties
            EdmNavigationProperty ordersNavProp = customer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "Orders",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = order
            });

            mary.AddNavigationTarget(ordersNavProp, orders);
            vipCustomer.AddNavigationTarget(ordersNavProp, orders);
            customers.AddNavigationTarget(ordersNavProp, orders);
            orders.AddNavigationTarget(
                order.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name = "Customer",
                TargetMultiplicity = EdmMultiplicity.ZeroOrOne,
                Target             = customer
            }),
                customers);

            // navigation properties on derived types.
            EdmNavigationProperty specialOrdersNavProp = specialCustomer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "SpecialOrders",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = order
            });

            vipCustomer.AddNavigationTarget(specialOrdersNavProp, orders);
            customers.AddNavigationTarget(specialOrdersNavProp, orders);
            orders.AddNavigationTarget(
                specialOrder.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name = "SpecialCustomer",
                TargetMultiplicity = EdmMultiplicity.ZeroOrOne,
                Target             = customer
            }),
                customers);

            model.SetAnnotationValue <BindableOperationFinder>(model, new BindableOperationFinder(model));

            // set properties
            Model                     = model;
            Container                 = container;
            Customer                  = customer;
            Order                     = order;
            Address                   = address;
            Account                   = account;
            SpecialCustomer           = specialCustomer;
            SpecialOrder              = specialOrder;
            Orders                    = orders;
            Customers                 = customers;
            VipCustomer               = vipCustomer;
            Mary                      = mary;
            RootOrder                 = rootOrder;
            OrderLine                 = orderLine;
            OrderLines                = orderLines;
            NonContainedOrderLines    = nonContainedOrderLines;
            UpgradeCustomer           = upgrade;
            UpgradeSpecialCustomer    = specialUpgrade;
            CustomerName              = customerName;
            IsCustomerUpgraded        = isCustomerUpgradedWithParam;
            IsSpecialCustomerUpgraded = IsSpecialUpgraded;
            Tag = tag;
        }
        private static IEdmModel GetTypelessEdmModel()
        {
            EdmModel model = new EdmModel();

            // Enum type "Color"
            EdmEnumType colorEnum = new EdmEnumType("NS", "Color");

            colorEnum.AddMember(new EdmEnumMember(colorEnum, "Red", new EdmEnumMemberValue(0)));
            colorEnum.AddMember(new EdmEnumMember(colorEnum, "Blue", new EdmEnumMemberValue(1)));
            colorEnum.AddMember(new EdmEnumMember(colorEnum, "Green", new EdmEnumMemberValue(2)));
            model.AddElement(colorEnum);

            // complex type "Address"
            EdmComplexType address = new EdmComplexType("NS", "Address");

            address.AddStructuralProperty("Street", EdmPrimitiveTypeKind.String);
            address.AddStructuralProperty("City", EdmPrimitiveTypeKind.String);
            model.AddElement(address);

            // derived complex type "SubAddress"
            EdmComplexType subAddress = new EdmComplexType("NS", "SubAddress", address);

            subAddress.AddStructuralProperty("Code", EdmPrimitiveTypeKind.Double);
            model.AddElement(subAddress);

            // entity type "Customer"
            EdmEntityType customer = new EdmEntityType("NS", "Customer");

            customer.AddKeys(customer.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
            customer.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            customer.AddStructuralProperty("Location", new EdmComplexTypeReference(address, isNullable: true));
            model.AddElement(customer);

            // derived entity type special customer
            EdmEntityType specialCustomer = new EdmEntityType("NS", "SpecialCustomer", customer);

            specialCustomer.AddStructuralProperty("Title", EdmPrimitiveTypeKind.Guid);
            model.AddElement(specialCustomer);

            // entity sets
            EdmEntityContainer container = new EdmEntityContainer("NS", "Default");

            model.AddElement(container);
            container.AddEntitySet("FCustomers", customer);

            EdmComplexTypeReference    complexType           = new EdmComplexTypeReference(address, isNullable: true);
            EdmCollectionTypeReference complexCollectionType = new EdmCollectionTypeReference(new EdmCollectionType(complexType));

            EdmEnumTypeReference       enumType           = new EdmEnumTypeReference(colorEnum, isNullable: false);
            EdmCollectionTypeReference enumCollectionType = new EdmCollectionTypeReference(new EdmCollectionType(enumType));

            EdmEntityTypeReference     entityType           = new EdmEntityTypeReference(customer, isNullable: false);
            EdmCollectionTypeReference entityCollectionType = new EdmCollectionTypeReference(new EdmCollectionType(entityType));

            IEdmTypeReference          intType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Int32, isNullable: true);
            EdmCollectionTypeReference primitiveCollectionType = new EdmCollectionTypeReference(new EdmCollectionType(intType));

            // bound functions
            BoundFunction(model, "IntCollectionFunction", "intValues", primitiveCollectionType, entityType);

            BoundFunction(model, "ComplexFunction", "address", complexType, entityType);

            BoundFunction(model, "ComplexCollectionFunction", "addresses", complexCollectionType, entityType);

            BoundFunction(model, "EnumFunction", "color", enumType, entityType);

            BoundFunction(model, "EnumCollectionFunction", "colors", enumCollectionType, entityType);

            BoundFunction(model, "EntityFunction", "customer", entityType, entityType);

            BoundFunction(model, "CollectionEntityFunction", "customers", entityCollectionType, entityType);

            // unbound functions
            UnboundFunction(container, "UnboundIntCollectionFunction", "intValues", primitiveCollectionType);

            UnboundFunction(container, "UnboundComplexFunction", "address", complexType);

            UnboundFunction(container, "UnboundComplexCollectionFunction", "addresses", complexCollectionType);

            UnboundFunction(container, "UnboundEnumFunction", "color", enumType);

            UnboundFunction(container, "UnboundEnumCollectionFunction", "colors", enumCollectionType);

            UnboundFunction(container, "UnboundEntityFunction", "customer", entityType);

            UnboundFunction(container, "UnboundCollectionEntityFunction", "customers", entityCollectionType);

            // bound to collection
            BoundToCollectionFunction(model, "BoundToCollectionFunction", "p", intType, entityType);

            model.SetAnnotationValue <BindableOperationFinder>(model, new BindableOperationFinder(model));
            return(model);
        }
예제 #6
0
        public void ParseCompositeKeyReference(TestODataUrlKeyDelimiter testODataUrlKeyDelimiter, string fullUrl)
        {
            var model = new EdmModel();

            var customer   = new EdmEntityType("Test", "Customer", null, false, true);
            var customerId = customer.AddStructuralProperty("id", EdmPrimitiveTypeKind.String, false);

            customer.AddKeys(customerId);
            model.AddElement(customer);

            var order           = new EdmEntityType("Test", "Order", null, false, true);
            var orderCustomerId = order.AddStructuralProperty("customerId", EdmPrimitiveTypeKind.String, true);
            var orderOrderId    = order.AddStructuralProperty("orderId", EdmPrimitiveTypeKind.String, true);

            order.AddKeys(orderCustomerId, orderOrderId);
            model.AddElement(order);

            var customerOrders = customer.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                ContainsTarget      = true,
                Name                = "orders",
                Target              = order,
                TargetMultiplicity  = EdmMultiplicity.Many,
                DependentProperties = new[] { customerId },
                PrincipalProperties = new[] { orderCustomerId }
            });

            var detail           = new EdmEntityType("Test", "Detail");
            var detailCustomerId = detail.AddStructuralProperty("customerId", EdmPrimitiveTypeKind.String);
            var detailOrderId    = detail.AddStructuralProperty("orderId", EdmPrimitiveTypeKind.String);

            detail.AddKeys(detailCustomerId, detailOrderId,
                           detail.AddStructuralProperty("id", EdmPrimitiveTypeKind.Int32, false));
            model.AddElement(detail);

            var detailedOrder        = new EdmEntityType("Test", "DetailedOrder", order);
            var detailedOrderDetails = detailedOrder.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                ContainsTarget     = true,
                Target             = detail,
                TargetMultiplicity = EdmMultiplicity.Many,
                Name = "details",
                DependentProperties = new[] { orderOrderId, orderCustomerId },
                PrincipalProperties = new[] { detailOrderId, detailCustomerId }
            });

            model.AddElement(detailedOrder);

            var container = new EdmEntityContainer("Test", "Container");
            var customers = container.AddEntitySet("customers", customer);

            model.AddElement(container);

            var parser = new ODataUriParser(model, new Uri("http://host"), new Uri(fullUrl));

            switch (testODataUrlKeyDelimiter)
            {
            case TestODataUrlKeyDelimiter.Parentheses:
                parser.UrlKeyDelimiter = ODataUrlKeyDelimiter.Parentheses;
                break;

            case TestODataUrlKeyDelimiter.Slash:
                parser.UrlKeyDelimiter = ODataUrlKeyDelimiter.Slash;
                break;

            default:
                Assert.True(false, "Unreachable code path");
                break;
            }

            var path = parser.ParsePath().ToList();

            path[0].ShouldBeEntitySetSegment(customers);
            path[1].ShouldBeKeySegment(new KeyValuePair <string, object>("id", "customerId"));
            path[2].ShouldBeNavigationPropertySegment(customerOrders);
            path[3].ShouldBeKeySegment(new KeyValuePair <string, object>("customerId", "customerId"),
                                       new KeyValuePair <string, object>("orderId", "orderId"));
            if (path.Count > 4)
            {
                // For tests with a type cast and a second-level navigation property.
                path[4].ShouldBeTypeSegment(detailedOrder);
                path[5].ShouldBeNavigationPropertySegment(detailedOrderDetails);
                path[6].ShouldBeKeySegment(new KeyValuePair <string, object>("customerId", "customerId"),
                                           new KeyValuePair <string, object>("orderId", "orderId"),
                                           new KeyValuePair <string, object>("id", 1));
            }
        }
예제 #7
0
        public static IEdmModel GetEdmModel()
        {
            if (_edmModel != null)
            {
                return(_edmModel);
            }

            EdmModel model = new EdmModel();

            // entity type 'Customer' with single alternate keys
            EdmEntityType customer = new EdmEntityType("NS", "Customer");

            customer.AddKeys(customer.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            customer.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            var ssn = customer.AddStructuralProperty("SSN", EdmPrimitiveTypeKind.String);

            model.AddAlternateKeyAnnotation(customer, new Dictionary <string, IEdmProperty>
            {
                { "SSN", ssn }
            });
            model.AddElement(customer);

            // entity type 'Order' with multiple alternate keys
            EdmEntityType order = new EdmEntityType("NS", "Order");

            order.AddKeys(order.AddStructuralProperty("OrderId", EdmPrimitiveTypeKind.Int32));
            var orderName  = order.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            var orderToken = order.AddStructuralProperty("Token", EdmPrimitiveTypeKind.Guid);

            order.AddStructuralProperty("Amount", EdmPrimitiveTypeKind.Int32);
            model.AddAlternateKeyAnnotation(order, new Dictionary <string, IEdmProperty>
            {
                { "Name", orderName }
            });

            model.AddAlternateKeyAnnotation(order, new Dictionary <string, IEdmProperty>
            {
                { "Token", orderToken }
            });

            model.AddElement(order);

            // entity type 'Person' with composed alternate keys
            EdmEntityType person = new EdmEntityType("NS", "Person");

            person.AddKeys(person.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            var countryRegion = person.AddStructuralProperty("Country_Region", EdmPrimitiveTypeKind.String);
            var passport      = person.AddStructuralProperty("Passport", EdmPrimitiveTypeKind.String);

            model.AddAlternateKeyAnnotation(person, new Dictionary <string, IEdmProperty>
            {
                { "Country_Region", countryRegion },
                { "Passport", passport }
            });
            model.AddElement(person);

            // complex type address
            EdmComplexType address = new EdmComplexType("NS", "Address");
            var            street  = address.AddStructuralProperty("Street", EdmPrimitiveTypeKind.String);
            var            city    = address.AddStructuralProperty("City", EdmPrimitiveTypeKind.String);

            model.AddElement(address);

            // entity type 'Company' with complex type alternate keys
            EdmEntityType company = new EdmEntityType("NS", "Company");

            company.AddKeys(company.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            company.AddStructuralProperty("Location", new EdmComplexTypeReference(address, isNullable: true));
            model.AddAlternateKeyAnnotation(company, new Dictionary <string, IEdmProperty>
            {
                { "City", city },
                { "Street", street }
            });
            model.AddElement(company);

            // entity sets
            EdmEntityContainer container = new EdmEntityContainer("NS", "Default");

            model.AddElement(container);
            container.AddEntitySet("Customers", customer);
            container.AddEntitySet("Orders", order);
            container.AddEntitySet("People", person);
            container.AddEntitySet("Companies", company);

            return(_edmModel = model);
        }
        public void Initialize()
        {
            // Initialize open EntityType: EntityType.
            EdmModel edmModel = new EdmModel();

            myInt32 = new EdmTypeDefinition("TestNamespace", "MyInt32", EdmPrimitiveTypeKind.Int32);
            EdmTypeDefinitionReference myInt32Reference = new EdmTypeDefinitionReference(myInt32, true);

            edmModel.AddElement(myInt32);

            myString = new EdmTypeDefinition("TestNamespace", "MyString", EdmPrimitiveTypeKind.String);
            EdmTypeDefinitionReference myStringReference = new EdmTypeDefinitionReference(myString, true);

            edmModel.AddElement(myString);

            EdmEntityType edmEntityType = new EdmEntityType("TestNamespace", "EntityType", baseType: null, isAbstract: false, isOpen: true);

            edmEntityType.AddStructuralProperty("DeclaredProperty", EdmPrimitiveTypeKind.Guid);
            edmEntityType.AddStructuralProperty("DeclaredGeometryProperty", EdmPrimitiveTypeKind.Geometry);
            edmEntityType.AddStructuralProperty("DeclaredSingleProperty", EdmPrimitiveTypeKind.Single);
            edmEntityType.AddStructuralProperty("DeclaredDoubleProperty", EdmPrimitiveTypeKind.Double);
            edmEntityType.AddStructuralProperty("MyInt32Property", myInt32Reference);
            edmEntityType.AddStructuralProperty("MyStringProperty", myStringReference);
            edmEntityType.AddStructuralProperty("TimeOfDayProperty", EdmPrimitiveTypeKind.TimeOfDay);
            edmEntityType.AddStructuralProperty("DateProperty", EdmPrimitiveTypeKind.Date);

            edmModel.AddElement(edmEntityType);

            this.model            = TestUtils.WrapReferencedModelsToMainModel(edmModel);
            this.entityType       = edmEntityType;
            this.declaredProperty = new ODataProperty {
                Name = "DeclaredProperty", Value = Guid.Empty
            };
            this.undeclaredProperty = new ODataProperty {
                Name = "UndeclaredProperty", Value = DateTimeOffset.MinValue
            };
            this.declaredGeometryProperty = new ODataProperty {
                Name = "DeclaredGeometryProperty", Value = GeometryPoint.Create(0.0, 0.0)
            };
            this.declaredPropertyTimeOfDay = new ODataProperty {
                Name = "TimeOfDayProperty", Value = new TimeOfDay(1, 30, 5, 123)
            };
            this.declaredPropertyDate = new ODataProperty {
                Name = "DateProperty", Value = new Date(2014, 9, 17)
            };

            // Initialize derived ComplexType: Address and HomeAddress
            this.addressType = new EdmComplexType("TestNamespace", "Address", baseType: null, isAbstract: false, isOpen: false);
            this.addressType.AddStructuralProperty("City", EdmPrimitiveTypeKind.String);
            this.derivedAddressType = new EdmComplexType("TestNamespace", "HomeAddress", baseType: this.addressType, isAbstract: false, isOpen: false);
            this.derivedAddressType.AddStructuralProperty("FamilyName", EdmPrimitiveTypeKind.String);

            // Initialize open ComplexType: OpenAddress.
            this.openAddressType = new EdmComplexType("TestNamespace", "OpenAddress", baseType: null, isAbstract: false, isOpen: true);
            this.openAddressType.AddStructuralProperty("CountryRegion", EdmPrimitiveTypeKind.String);

            edmModel.AddElement(this.addressType);
            edmModel.AddElement(this.derivedAddressType);
            edmModel.AddElement(this.openAddressType);

            this.declaredPropertyAddress = new ODataProperty()
            {
                Name = "AddressProperty", Value = new ODataComplexValue {
                    TypeName = "TestNamespace.Address", Properties = new ODataProperty[] { new ODataProperty {
                                                                                               Name = "City", Value = "Shanghai"
                                                                                           } }
                }
            };
            this.declaredPropertyHomeAddress = new ODataProperty()
            {
                Name = "HomeAddressProperty", Value = new ODataComplexValue {
                    TypeName = "TestNamespace.HomeAddress", Properties = new ODataProperty[] { new ODataProperty {
                                                                                                   Name = "FamilyName", Value = "Green"
                                                                                               }, new ODataProperty {
                                                                                                   Name = "City", Value = "Shanghai"
                                                                                               } }
                }
            };
            this.declaredPropertyAddressWithInstanceAnnotation = new ODataProperty()
            {
                Name  = "AddressProperty",
                Value = new ODataComplexValue
                {
                    TypeName   = "TestNamespace.Address",
                    Properties = new ODataProperty[]
                    {
                        new ODataProperty {
                            Name = "City", Value = "Shanghai"
                        }
                    },
                    InstanceAnnotations = new Collection <ODataInstanceAnnotation>
                    {
                        new ODataInstanceAnnotation("Is.ReadOnly", new ODataPrimitiveValue(true))
                    }
                }
            };
            this.declaredPropertyHomeAddressWithInstanceAnnotations = new ODataProperty()
            {
                Name  = "HomeAddressProperty",
                Value = new ODataComplexValue
                {
                    TypeName   = "TestNamespace.HomeAddress",
                    Properties = new ODataProperty[]
                    {
                        new ODataProperty
                        {
                            Name  = "FamilyName",
                            Value = "Green",
                            InstanceAnnotations = new Collection <ODataInstanceAnnotation>
                            {
                                new ODataInstanceAnnotation("FamilyName.annotation", new ODataPrimitiveValue(true))
                            }
                        },
                        new ODataProperty
                        {
                            Name  = "City",
                            Value = "Shanghai",
                            InstanceAnnotations = new Collection <ODataInstanceAnnotation>
                            {
                                new ODataInstanceAnnotation("City.annotation1", new ODataPrimitiveValue(true)),
                                new ODataInstanceAnnotation("City.annotation2", new ODataPrimitiveValue(123))
                            }
                        }
                    },
                    InstanceAnnotations = new Collection <ODataInstanceAnnotation>
                    {
                        new ODataInstanceAnnotation("Is.AutoComputable", new ODataPrimitiveValue(true)),
                        new ODataInstanceAnnotation("Is.ReadOnly", new ODataPrimitiveValue(false))
                    }
                }
            };
            this.declaredPropertyCountryRegion = new ODataProperty()
            {
                Name = "CountryRegion", Value = "China"
            };
            this.declaredPropertyCountryRegionWithInstanceAnnotation = new ODataProperty()
            {
                Name  = "CountryRegion",
                Value = "China",
                InstanceAnnotations = new Collection <ODataInstanceAnnotation>
                {
                    new ODataInstanceAnnotation("Is.ReadOnly", new ODataPrimitiveValue(true))
                }
            };
            this.undeclaredPropertyCity = new ODataProperty()
            {
                Name = "City", Value = "Shanghai"
            };
            this.declaredPropertyMyInt32 = new ODataProperty()
            {
                Name = "MyInt32Property", Value = 12345
            };
            this.declaredPropertyMyInt32WithInstanceAnnotations = new ODataProperty()
            {
                Name  = "MyInt32Property",
                Value = 12345,
                InstanceAnnotations = new Collection <ODataInstanceAnnotation>
                {
                    new ODataInstanceAnnotation("Is.AutoComputable", new ODataPrimitiveValue(true)),
                    new ODataInstanceAnnotation("Is.ReadOnly", new ODataPrimitiveValue(false))
                }
            };
            this.declaredPropertyMyString = new ODataProperty()
            {
                Name = "MyStringProperty", Value = "abcde"
            };
        }
예제 #9
0
        public void WriterShouldNotIncludeTypeNameForCollectionOfDerivedType()
        {
            // JSON Light: writer doesn't include type name for collection of derived type
            // If I have a collection property declared in metadata as Collection(Edm.Geography),
            // and at serialization type, it's clearly a Collection(Edm.GeographyPoint),
            // we won't write the type name for that property by default (i.e., minimal metadata mode).

            var model      = new EdmModel();
            var entityType = new EdmEntityType("Var1", "Type");

            entityType.AddKeys(entityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
            entityType.AddProperty(new EdmStructuralProperty(entityType, "Geographies", new EdmCollectionTypeReference(new EdmCollectionType(EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geography, false)))));
            model.AddElement(entityType);

            var writerSettings = new ODataMessageWriterSettings();

            writerSettings.SetContentType(ODataFormat.Json);
            writerSettings.DisableMessageStreamDisposal = true;

            var message = new InMemoryMessage {
                Stream = new MemoryStream()
            };

            using (ODataMessageWriter odataMessageWriter = new ODataMessageWriter((IODataRequestMessage)message, writerSettings, model))
            {
                ODataWriter odataWriter = odataMessageWriter.CreateODataEntryWriter();
                odataWriter.WriteStart(
                    new ODataEntry
                {
                    TypeName   = "Var1.Type",
                    Properties = new[]
                    {
                        new ODataProperty()
                        {
                            Name  = "Id",
                            Value = 1
                        },
                        new ODataProperty()
                        {
                            Name  = "Geographies",
                            Value = new ODataCollectionValue
                            {
                                Items = new[]
                                {
                                    GeographyPoint.Create(0, 0),
                                    GeographyPoint.Create(1, 1),
                                    GeographyPoint.Create(2, 2)
                                }
                            }
                        },
                    }
                });
                odataWriter.WriteEnd();
                odataWriter.Flush();
            }

            message.Stream.Position = 0;
            var output = new StreamReader(message.Stream).ReadToEnd();

            Assert.IsFalse(output.Contains("Collection(Edm.GeographyPoint)"), @"output.Contains(""Collection(Edm.GeographyPoint)"" == false");
        }
예제 #10
0
        public static IEdmModel CreateServiceEdmModel(string ns)
        {
            EdmModel model            = new EdmModel();
            var      defaultContainer = new EdmEntityContainer(ns, "PerfInMemoryContainer");

            model.AddElement(defaultContainer);

            var personType       = new EdmEntityType(ns, "Person");
            var personIdProperty = new EdmStructuralProperty(personType, "PersonID", EdmCoreModel.Instance.GetInt32(false));

            personType.AddProperty(personIdProperty);
            personType.AddKeys(new IEdmStructuralProperty[] { personIdProperty });
            personType.AddProperty(new EdmStructuralProperty(personType, "FirstName", EdmCoreModel.Instance.GetString(false)));
            personType.AddProperty(new EdmStructuralProperty(personType, "LastName", EdmCoreModel.Instance.GetString(false)));
            personType.AddProperty(new EdmStructuralProperty(personType, "MiddleName", EdmCoreModel.Instance.GetString(true)));
            personType.AddProperty(new EdmStructuralProperty(personType, "Age", EdmCoreModel.Instance.GetInt32(false)));
            model.AddElement(personType);

            var simplePersonSet = new EdmEntitySet(defaultContainer, "SimplePeopleSet", personType);

            defaultContainer.AddElement(simplePersonSet);

            var largetPersonSet = new EdmEntitySet(defaultContainer, "LargePeopleSet", personType);

            defaultContainer.AddElement(largetPersonSet);

            var addressType = new EdmComplexType(ns, "Address");

            addressType.AddProperty(new EdmStructuralProperty(addressType, "Street", EdmCoreModel.Instance.GetString(false)));
            addressType.AddProperty(new EdmStructuralProperty(addressType, "City", EdmCoreModel.Instance.GetString(false)));
            addressType.AddProperty(new EdmStructuralProperty(addressType, "PostalCode", EdmCoreModel.Instance.GetString(false)));
            model.AddElement(addressType);

            var companyType = new EdmEntityType(ns, "Company");
            var companyId   = new EdmStructuralProperty(companyType, "CompanyID", EdmCoreModel.Instance.GetInt32(false));

            companyType.AddProperty(companyId);
            companyType.AddKeys(companyId);
            companyType.AddProperty(new EdmStructuralProperty(companyType, "Name", EdmCoreModel.Instance.GetString(true)));
            companyType.AddProperty(new EdmStructuralProperty(companyType, "Address", new EdmComplexTypeReference(addressType, true)));
            companyType.AddProperty(new EdmStructuralProperty(companyType, "Revenue", EdmCoreModel.Instance.GetInt32(false)));

            model.AddElement(companyType);

            var companySet = new EdmEntitySet(defaultContainer, "CompanySet", companyType);

            defaultContainer.AddElement(companySet);

            var companyEmployeeNavigation = companyType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo()
            {
                Name               = "Employees",
                Target             = personType,
                TargetMultiplicity = EdmMultiplicity.Many
            });

            companySet.AddNavigationTarget(companyEmployeeNavigation, largetPersonSet);

            // ResetDataSource
            var resetDataSourceAction = new EdmAction(ns, "ResetDataSource", null, false, null);

            model.AddElement(resetDataSourceAction);
            defaultContainer.AddActionImport(resetDataSourceAction);

            return(model);
        }
예제 #11
0
        private IEdmModel GetModel()
        {
            if (_model != null)
            {
                return(_model);
            }

            var model = new EdmModel();

            // EntityContainer: Service
            var container = new EdmEntityContainer("ns", "Service");

            model.AddElement(container);

            // EntityType: Address
            var address   = new EdmEntityType("ns", "Address");
            var addressId = address.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32);

            address.AddKeys(addressId);
            model.AddElement(address);

            // EntitySet: Addresses
            var addresses = container.AddEntitySet("Addresses", address);

            // EntityType: PaymentInstrument
            var paymentInstrument   = new EdmEntityType("ns", "PaymentInstrument");
            var paymentInstrumentId = paymentInstrument.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32);

            paymentInstrument.AddKeys(paymentInstrumentId);
            var billingAddresses = paymentInstrument.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "BillingAddresses",
                Target             = address,
                TargetMultiplicity = EdmMultiplicity.Many
            });

            paymentInstrument.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "ContainedBillingAddresses",
                Target             = address,
                TargetMultiplicity = EdmMultiplicity.Many,
                ContainsTarget     = true
            });
            model.AddElement(paymentInstrument);

            // EntityType: Account
            var account   = new EdmEntityType("ns", "Account");
            var accountId = account.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32);

            account.AddKeys(accountId);
            var myPaymentInstruments = account.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "MyPaymentInstruments",
                Target             = paymentInstrument,
                TargetMultiplicity = EdmMultiplicity.Many,
                ContainsTarget     = true
            });

            model.AddElement(account);

            // EntitySet: Accounts
            var accounts = container.AddEntitySet("Accounts", account);

            var paymentInstruments = accounts.FindNavigationTarget(myPaymentInstruments) as EdmNavigationSource;

            Assert.NotNull(paymentInstruments);
            paymentInstruments.AddNavigationTarget(billingAddresses, addresses);

            // EntityType: Person
            var person   = new EdmEntityType("ns", "Person");
            var personId = person.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32);

            person.AddKeys(personId);
            var myAccounts = person.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "MyAccounts",
                Target             = account,
                TargetMultiplicity = EdmMultiplicity.Many
            });
            var myPermanentAccount = person.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "MyPermanentAccount",
                Target             = account,
                TargetMultiplicity = EdmMultiplicity.One
            });
            var myLatestAccount = person.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "MyLatestAccount",
                Target             = account,
                TargetMultiplicity = EdmMultiplicity.One
            });

            person.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "MyAddresses",
                Target             = address,
                TargetMultiplicity = EdmMultiplicity.Many,
                ContainsTarget     = true
            });
            model.AddElement(person);

            // EntityType: Benefit
            var benefit   = new EdmEntityType("ns", "Benefit");
            var benefitId = benefit.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32);

            benefit.AddKeys(benefitId);
            model.AddElement(benefit);

            // EntityType: SpecialPerson
            var specialPerson = new EdmEntityType("ns", "SpecialPerson", person);

            specialPerson.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "Benefits",
                Target             = benefit,
                TargetMultiplicity = EdmMultiplicity.Many,
                ContainsTarget     = true
            });
            model.AddElement(specialPerson);

            // EntityType: VIP
            var vip = new EdmEntityType("ns", "VIP", specialPerson);

            vip.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "MyBenefits",
                Target             = benefit,
                TargetMultiplicity = EdmMultiplicity.Many,
                ContainsTarget     = true
            });
            model.AddElement(vip);

            // EntitySet: People
            var people = container.AddEntitySet("People", person);

            people.AddNavigationTarget(myAccounts, accounts);
            people.AddNavigationTarget(myLatestAccount, accounts);

            // EntityType: Club
            var club   = new EdmEntityType("ns", "Club");
            var clubId = club.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32);

            club.AddKeys(clubId);
            var members = club.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "Members",
                Target             = person,
                TargetMultiplicity = EdmMultiplicity.Many,
                ContainsTarget     = true
            });

            // EntityType: SeniorClub
            var seniorClub = new EdmEntityType("ns", "SeniorClub", club);

            model.AddElement(seniorClub);

            // EntitySet: Clubs
            var clubs         = container.AddEntitySet("Clubs", club);
            var membersInClub = clubs.FindNavigationTarget(members) as EdmNavigationSource;

            membersInClub.AddNavigationTarget(myAccounts, accounts);

            // Singleton: PermanentAccount
            var permanentAccount = container.AddSingleton("PermanentAccount", account);

            people.AddNavigationTarget(myPermanentAccount, permanentAccount);

            _model = model;

            return(_model);
        }
예제 #12
0
        /// <summary>
        /// Creates several PayloadTestDescriptors containing Batch Requests
        /// </summary>
        /// <param name="requestManager">Used for building the requests</param>
        /// <param name="model">The model to use for adding additional types.</param>
        /// <param name="withTypeNames">Whether or not to use full type names.</param>
        /// <returns>PayloadTestDescriptors</returns>
        public static IEnumerable <PayloadTestDescriptor> CreateBatchRequestTestDescriptors(
            IODataRequestManager requestManager,
            EdmModel model,
            bool withTypeNames = false)
        {
            ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager");
            EdmEntityType      personType       = null;
            EdmComplexType     carType          = null;
            EdmEntitySet       personsEntitySet = null;
            EdmEntityContainer container        = model.EntityContainer as EdmEntityContainer;

            if (model != null)
            {
                //TODO: Clone EdmModel
                //model = model.Clone();

                if (container == null)
                {
                    container = new EdmEntityContainer("TestModel", "DefaultContainer");
                    model.AddElement(container);
                }

                personType = model.FindDeclaredType("TestModel.TFPerson") as EdmEntityType;
                carType    = model.FindDeclaredType("TestModel.TFCar") as EdmComplexType;

                // Create the metadata types for the entity instance used in the entity set
                if (carType == null)
                {
                    carType = new EdmComplexType("TestModel", "TFCar");
                    model.AddElement(carType);
                    carType.AddStructuralProperty("Make", EdmPrimitiveTypeKind.String, true);
                    carType.AddStructuralProperty("Color", EdmPrimitiveTypeKind.String, true);
                }

                if (personType == null)
                {
                    personType = new EdmEntityType("TestModel", "TFPerson");
                    model.AddElement(personType);
                    personType.AddKeys(personType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
                    personType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String, true);
                    personType.AddStructuralProperty("Car", carType.ToTypeReference());
                    container.AddEntitySet("Customers", personType);
                }

                personsEntitySet = container.AddEntitySet("People", personType);
            }

            ComplexInstance carInstance = PayloadBuilder.ComplexValue(withTypeNames ? "TestModel.TFCar" : null)
                                          .Property("Make", PayloadBuilder.PrimitiveValue("Ford"))
                                          .Property("Color", PayloadBuilder.PrimitiveValue("Blue"));
            ComplexProperty carProperty = (ComplexProperty)PayloadBuilder.Property("Car", carInstance)
                                          .WithTypeAnnotation(personType);

            EntityInstance personInstance = PayloadBuilder.Entity(withTypeNames ? "TestModel.TFPerson" : null)
                                            .Property("Id", PayloadBuilder.PrimitiveValue(1))
                                            .Property("Name", PayloadBuilder.PrimitiveValue("John Doe"))
                                            .Property("Car", carInstance)
                                            .WithTypeAnnotation(personType);

            var carPropertyPayload = new PayloadTestDescriptor()
            {
                PayloadElement  = carProperty,
                PayloadEdmModel = model
            };

            var emptyPayload = new PayloadTestDescriptor()
            {
                PayloadEdmModel = CreateEmptyEdmModel()
            };

            var personPayload = new PayloadTestDescriptor()
            {
                PayloadElement  = personInstance,
                PayloadEdmModel = model
            };

            var root      = ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc"));
            var entityset = ODataUriBuilder.EntitySet(personsEntitySet);

            // Get operations
            var queryOperation1 = emptyPayload.InRequestOperation(HttpVerb.Get, new ODataUri(new ODataUriSegment[] { root }), requestManager);
            var queryOperation2 = emptyPayload.InRequestOperation(HttpVerb.Get, new ODataUri(new ODataUriSegment[] { root }), requestManager);

            // Post operation containing a complex property
            var postOperation = carPropertyPayload.InRequestOperation(HttpVerb.Post, new ODataUri(new ODataUriSegment[] { root, entityset }), requestManager, MimeTypes.ApplicationJsonLight);
            // Delete operation with no payload
            var deleteOperation = emptyPayload.InRequestOperation(HttpVerb.Delete, new ODataUri(new ODataUriSegment[] { root, entityset }), requestManager);
            // Put operation where the payload is an EntityInstance
            var putOperation = personPayload.InRequestOperation(HttpVerb.Put, new ODataUri(new ODataUriSegment[] { root, entityset }), requestManager);

            // A changeset containing a delete with no payload and a put
            var twoOperationsChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { postOperation, deleteOperation }, requestManager);
            // A changeset containing a delete with no payload
            var oneOperationChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { deleteOperation }, requestManager);
            // A changeset containing a put, post and delete
            var threeOperationsChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { putOperation, postOperation, deleteOperation }, requestManager);
            // A changeset containing no operations
            var emptyChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { }, requestManager);

            // Empty Batch
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload()
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_emptybatch")),
                PayloadEdmModel = emptyPayload.PayloadEdmModel,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            // Single Operation
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_singleoperation")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            // Multiple Operations
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, queryOperation2)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_multipleoperations")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            // Single Changeset
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(twoOperationsChangeset)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_singlechangeset")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            // Multiple Changesets (different content types)
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(twoOperationsChangeset, oneOperationChangeset, emptyChangeset)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_multiplechangesets")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            // Operations and changesets
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(twoOperationsChangeset, queryOperation1, oneOperationChangeset)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_1")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, oneOperationChangeset, queryOperation2)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_2")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, queryOperation2, twoOperationsChangeset, oneOperationChangeset)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_3")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, threeOperationsChangeset, queryOperation2, twoOperationsChangeset, queryOperation1, oneOperationChangeset)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_4")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, emptyChangeset, queryOperation1, threeOperationsChangeset, queryOperation2, oneOperationChangeset)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_5")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });
        }
예제 #13
0
        /// <summary>
        /// Creates several PayloadTestDescriptors containing Batch Responses
        /// </summary>
        /// <param name="requestManager">Used for building the requests/responses.</param>
        /// <param name="model">The model to use for adding additional types.</param>
        /// <param name="withTypeNames">Whether or not to use full type names.</param>
        /// <returns>PayloadTestDescriptors</returns>
        public static IEnumerable <PayloadTestDescriptor> CreateBatchResponseTestDescriptors(
            IODataRequestManager requestManager,
            EdmModel model,
            bool withTypeNames = false)
        {
            EdmEntityType  personType = null;
            EdmComplexType carType    = null;

            if (model != null)
            {
                //TODO: CLONE for EdmModel
                //model = model.Clone();

                personType = model.FindDeclaredType("TestModel.TFPerson") as EdmEntityType;
                carType    = model.FindDeclaredType("TestModel.TFCar") as EdmComplexType;

                // Create the metadata types for the entity instance used in the entity set
                if (carType == null)
                {
                    carType = new EdmComplexType("TestModel", "TFCar");
                    model.AddElement(carType);
                    carType.AddStructuralProperty("Make", EdmPrimitiveTypeKind.String, true);
                    carType.AddStructuralProperty("Color", EdmPrimitiveTypeKind.String, true);
                }

                if (personType == null)
                {
                    personType = new EdmEntityType("TestModel", "TFPerson");
                    model.AddElement(personType);
                    personType.AddKeys(personType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
                    personType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String, true);
                    personType.AddStructuralProperty("Car", carType.ToTypeReference());

                    EdmEntityContainer container = (EdmEntityContainer)model.EntityContainer;
                    if (container == null)
                    {
                        container = new EdmEntityContainer("TestModel", "DefaultContainer");
                        model.AddElement(container);
                        container.AddEntitySet("Customers", personType);
                        container.AddEntitySet("TFPerson", personType);
                    }
                }
            }

            ComplexInstance carInstance = PayloadBuilder.ComplexValue(withTypeNames ? "TestModel.TFCar" : null)
                                          .Property("Make", PayloadBuilder.PrimitiveValue("Ford"))
                                          .Property("Color", PayloadBuilder.PrimitiveValue("Blue"));
            ComplexProperty carProperty = (ComplexProperty)PayloadBuilder.Property("Car", carInstance)
                                          .WithTypeAnnotation(carType);

            EntityInstance personInstance = PayloadBuilder.Entity(withTypeNames ? "TestModel.TFPerson" : null)
                                            .Property("Id", PayloadBuilder.PrimitiveValue(1))
                                            .Property("Name", PayloadBuilder.PrimitiveValue("John Doe"))
                                            .Property("Car", carInstance)
                                            .WithTypeAnnotation(personType);

            ODataErrorPayload errorInstance = PayloadBuilder.Error("ErrorCode")
                                              .Message("ErrorValue")
                                              .InnerError(
                PayloadBuilder.InnerError().Message("InnerErrorMessage").StackTrace("InnerErrorStackTrace").TypeName("InnerErrorTypeName"));

            var carPropertyPayload = new PayloadTestDescriptor()
            {
                PayloadElement  = carProperty,
                PayloadEdmModel = model
            };

            var emptyPayload = new PayloadTestDescriptor()
            {
                PayloadEdmModel = CreateEmptyEdmModel()
            };

            var personPayload = new PayloadTestDescriptor()
            {
                // This payload will be serialised to JSON so we need the annotation to mark it as a response.
                PayloadElement = personInstance.AddAnnotation(new PayloadFormatVersionAnnotation()
                {
                    Response = true, ResponseWrapper = true
                }),
                PayloadEdmModel = model
            };

            var errorPayload = new PayloadTestDescriptor()
            {
                PayloadElement  = errorInstance,
                PayloadEdmModel = model,
            };

            // response operation with a status code of 5 containing a complex instance
            var carPropertyPayloadOperation = carPropertyPayload.InResponseOperation(5, requestManager);
            // response operation with no payload and a status code of 200
            var emptyPayloadOperation = emptyPayload.InResponseOperation(200, requestManager);
            // response operation with a status code of 418 containing an entity instance
            var personPayloadOperation = personPayload.InResponseOperation(418, requestManager, MimeTypes.ApplicationJsonLight);
            // response operation with a status code of 404 containing an error instance
            var errorPayloadOperation = errorPayload.InResponseOperation(404, requestManager);

            // changeset with multiple operations
            var twoOperationsChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { carPropertyPayloadOperation, emptyPayloadOperation }, requestManager);
            // changesets with a single operation
            var oneOperationChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { personPayloadOperation }, requestManager);
            var oneErrorChangeset     = BatchUtils.GetResponseChangeset(new IMimePart[] { errorPayloadOperation }, requestManager);
            // empty changeset
            var emptyChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { }, requestManager);

            // Empty Batch
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] {  })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_emptybatch")),
                PayloadEdmModel = emptyPayload.PayloadEdmModel,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            // Single Operation
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_singleoperation")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            // Multiple Operations
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation, emptyPayloadOperation, errorPayloadOperation, personPayloadOperation })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_multipleoperations")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            // Single Changeset
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_singlechangeset")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            // Multiple Changesets
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset, oneOperationChangeset })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_multiplechangesets")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            // Operations and changesets
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset, carPropertyPayloadOperation, oneOperationChangeset })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_1")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation, oneOperationChangeset, emptyPayloadOperation })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_2")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { errorPayloadOperation, carPropertyPayloadOperation, emptyPayloadOperation, twoOperationsChangeset, oneOperationChangeset })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_3")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(
                    new IMimePart[] { oneErrorChangeset, carPropertyPayloadOperation, emptyChangeset, emptyPayloadOperation, twoOperationsChangeset, personPayloadOperation, oneOperationChangeset, errorPayloadOperation })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_4")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });
        }
        private void BuildOperations(EdmModel model, string modelNamespace)
        {
            foreach (OperationMethodInfo operationMethodInfo in this.operationInfos)
            {
                // With this method, if return type is nullable type,it will get underlying type
                var returnType = TypeHelper.GetUnderlyingTypeOrSelf(operationMethodInfo.Method.ReturnType);
                var returnTypeReference = returnType.GetReturnTypeReference(model);
                bool isBound = operationMethodInfo.IsBound;
                var bindingParameter = operationMethodInfo.Method.GetParameters().FirstOrDefault();

                if (bindingParameter == null && isBound)
                {
                    // Ignore the method which is marked as bounded but no parameters
                    continue;
                }

                string namespaceName = GetNamespaceName(operationMethodInfo, modelNamespace);

                EdmOperation operation = null;
                EdmPathExpression path = null;
                if (isBound)
                {
                    // Unbound actions or functions should not have EntitySetPath attribute
                    path = BuildBoundOperationReturnTypePathExpression(returnTypeReference, bindingParameter);
                }

                if (operationMethodInfo.HasSideEffects)
                {
                    operation = new EdmAction(
                        namespaceName,
                        operationMethodInfo.Name,
                        returnTypeReference,
                        isBound,
                        path);
                }
                else
                {
                    operation = new EdmFunction(
                        namespaceName,
                        operationMethodInfo.Name,
                        returnTypeReference,
                        isBound,
                        path,
                        operationMethodInfo.IsComposable);
                }

                BuildOperationParameters(operation, operationMethodInfo.Method, model);
                model.AddElement(operation);

                if (!isBound)
                {
                    // entitySetReferenceExpression refer to an entity set containing entities returned
                    // by this function/action import.
                    var entitySetExpression = BuildEntitySetExpression(
                        model, operationMethodInfo.EntitySet, returnTypeReference);
                    var entityContainer = model.EnsureEntityContainer(this.targetType);
                    if (operationMethodInfo.HasSideEffects)
                    {
                        entityContainer.AddActionImport(operation.Name, (EdmAction)operation, entitySetExpression);
                    }
                    else
                    {
                        entityContainer.AddFunctionImport(
                            operation.Name, (EdmFunction)operation, entitySetExpression);
                    }
                }
            }
        }
예제 #15
0
        public EdmModel BuildEdmModel()
        {
            Dictionary <Type, EntityTypeInfo> entityTypeInfos = BuildEntityTypes();

            foreach (EntityTypeInfo typeInfo in entityTypeInfos.Values)
            {
                typeInfo.BuildProperties(entityTypeInfos, _enumTypes, _complexTypes);
            }

            foreach (EntityTypeInfo typeInfo in entityTypeInfos.Values)
            {
                foreach (FKeyInfo fkeyInfo in typeInfo.NavigationClrProperties)
                {
                    fkeyInfo.EdmNavigationProperty = CreateNavigationProperty(fkeyInfo);
                }
            }

            var edmModel  = new EdmModel();
            var container = new EdmEntityContainer("Default", "Container");

            edmModel.AddElements(_enumTypes.Values);
            foreach (KeyValuePair <Type, EdmEnumType> enumType in _enumTypes)
            {
                edmModel.SetClrType(enumType.Value, enumType.Key);
            }

            edmModel.AddElements(_complexTypes.Values);
            foreach (KeyValuePair <Type, EdmComplexType> complexType in _complexTypes)
            {
                edmModel.SetClrType(complexType.Value, complexType.Key);
            }

            var entitySets = new Dictionary <IEdmEntityType, EdmEntitySet>(entityTypeInfos.Count);

            foreach (EntityTypeInfo typeInfo in entityTypeInfos.Values)
            {
                edmModel.AddElement(typeInfo.EdmType);
                edmModel.SetClrType(typeInfo.EdmType, typeInfo.ClrType);

                foreach (KeyValuePair <String, Type> pair in _entitySets)
                {
                    if (pair.Value == typeInfo.ClrType)
                    {
                        entitySets.Add(typeInfo.EdmType, container.AddEntitySet(pair.Key, typeInfo.EdmType));
                        break;
                    }
                }
            }

            var manyToManyBuilder = new ManyToManyBuilder(edmModel, _metadataProvider, entityTypeInfos);

            foreach (EntityTypeInfo typeInfo in entityTypeInfos.Values)
            {
                foreach (FKeyInfo fkeyInfo in typeInfo.NavigationClrProperties)
                {
                    EdmEntitySet principal = entitySets[fkeyInfo.PrincipalInfo.EdmType];
                    EdmEntitySet dependent = entitySets[fkeyInfo.DependentInfo.EdmType];

                    if (fkeyInfo.DependentNavigationProperty == null)
                    {
                        principal.AddNavigationTarget(fkeyInfo.EdmNavigationProperty, dependent);
                    }
                    else
                    {
                        dependent.AddNavigationTarget(fkeyInfo.EdmNavigationProperty, principal);
                        if (fkeyInfo.EdmNavigationProperty.Partner != null)
                        {
                            principal.AddNavigationTarget(fkeyInfo.EdmNavigationProperty.Partner, dependent);
                        }
                    }
                }

                manyToManyBuilder.Build(typeInfo);
            }

            foreach (OeOperationConfiguration operationConfiguration in _operationConfigurations)
            {
                if (operationConfiguration.IsEdmFunction)
                {
                    EdmFunction edmFunction = BuildFunction(operationConfiguration, entityTypeInfos);
                    if (edmFunction != null)
                    {
                        edmModel.AddElement(edmFunction);
                        container.AddFunctionImport(operationConfiguration.Name, edmFunction);
                        edmModel.SetIsDbFunction(edmFunction, operationConfiguration.IsDbFunction);
                    }
                }
                else
                {
                    EdmAction edmAction = BuildAction(operationConfiguration, entityTypeInfos);
                    if (edmAction != null)
                    {
                        edmModel.AddElement(edmAction);
                        container.AddActionImport(operationConfiguration.Name, edmAction);
                        edmModel.SetIsDbFunction(edmAction, operationConfiguration.IsDbFunction);
                    }
                }
            }

            edmModel.AddElement(container);
            return(edmModel);
        }
        public void NoMetadataTest()
        {
            EdmModel model     = new EdmModel();
            var      container = new EdmEntityContainer("TestModel", "DefaultContainer");

            model.AddElement(container);

            var testDescriptors = new[]
            {
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.EntitySet(),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.EntitySet(),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.EntitySet(),
                    PayloadEdmModel       = model,
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    //ExpectedException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_ResourceWithoutType"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.Entity(),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.Entity(),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.Entity(),
                    PayloadEdmModel       = model,
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ReaderValidationUtils_ResourceWithoutType"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.PrimitiveProperty("propertyName", 42),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.Property("propertyName", PayloadBuilder.ComplexValue()),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.Property("propertyName", PayloadBuilder.PrimitiveMultiValue()),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.PrimitiveCollection(),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.PrimitiveCollection(),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveCollection(),
                    //PayloadModel = model,
                    PayloadEdmModel       = model,
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ItemTypeRequiredForCollectionReaderInRequests"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.ComplexCollection(),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.ComplexCollection(),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.ComplexCollection(),
                    PayloadEdmModel       = model,
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ItemTypeRequiredForCollectionReaderInRequests"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.ServiceDocument().Workspace(PayloadBuilder.Workspace()),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.DeferredLink("http://odata.org/deferred"),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.DeferredLink("http://odata.org/deferred"),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.LinkCollection(),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.ComplexValue(),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.ComplexValue(),
                    PayloadEdmModel       = model,
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ArgumentNullException("ODataJsonLightInputContext_OperationCannotBeNullForCreateParameterReader", "operation")
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();
                testDescriptor.RunTest(testConfiguration);
            });
        }
        private static void AddOperations(this EdmModel model, IEnumerable <OperationConfiguration> configurations, EdmEntityContainer container,
                                          Dictionary <Type, IEdmType> edmTypeMap, IDictionary <string, EdmNavigationSource> edmNavigationSourceMap)
        {
            Contract.Assert(model != null, "Model can't be null");

            ValidateActionOverload(configurations.OfType <ActionConfiguration>());

            foreach (OperationConfiguration operationConfiguration in configurations)
            {
                IEdmTypeReference returnReference = GetEdmTypeReference(edmTypeMap,
                                                                        operationConfiguration.ReturnType,
                                                                        operationConfiguration.ReturnType != null && operationConfiguration.ReturnNullable);
                IEdmExpression     expression     = GetEdmEntitySetExpression(edmNavigationSourceMap, operationConfiguration);
                IEdmPathExpression pathExpression = operationConfiguration.EntitySetPath != null
                    ? new EdmPathExpression(operationConfiguration.EntitySetPath)
                    : null;

                EdmOperationImport operationImport;

                switch (operationConfiguration.Kind)
                {
                case OperationKind.Action:
                    operationImport = CreateActionImport(operationConfiguration, container, returnReference, expression, pathExpression);
                    break;

                case OperationKind.Function:
                    operationImport = CreateFunctionImport((FunctionConfiguration)operationConfiguration, container, returnReference, expression, pathExpression);
                    break;

                default:
                    Contract.Assert(false, "Unsupported OperationKind");
                    return;
                }

                EdmOperation operation = (EdmOperation)operationImport.Operation;
                if (operationConfiguration.IsBindable && operationConfiguration.Title != null && operationConfiguration.Title != operationConfiguration.Name)
                {
                    model.SetOperationTitleAnnotation(operation, new OperationTitleAnnotation(operationConfiguration.Title));
                }

                if (operationConfiguration.IsBindable &&
                    operationConfiguration.NavigationSource != null &&
                    edmNavigationSourceMap.ContainsKey(operationConfiguration.NavigationSource.Name))
                {
                    model.SetAnnotationValue(operation, new ReturnedEntitySetAnnotation(operationConfiguration.NavigationSource.Name));
                }

                AddOperationParameters(operation, operationConfiguration, edmTypeMap);

                if (operationConfiguration.IsBindable)
                {
                    AddOperationLinkBuilder(model, operation, operationConfiguration);
                    ValidateOperationEntitySetPath(model, operationImport, operationConfiguration);
                }
                else
                {
                    container.AddElement(operationImport);
                }

                model.AddElement(operation);
                model.SetVocabularyConfigurationAnnotations(operation, operationConfiguration);
            }
        }
예제 #18
0
        private static void AddProcedures(this EdmModel model, IEnumerable <ProcedureConfiguration> configurations, EdmEntityContainer container,
                                          Dictionary <Type, IEdmType> edmTypeMap, IDictionary <string, EdmNavigationSource> edmNavigationSourceMap)
        {
            Contract.Assert(model != null, "Model can't be null");

            ValidateActionOverload(configurations.OfType <ActionConfiguration>());

            foreach (ProcedureConfiguration procedure in configurations)
            {
                IEdmTypeReference returnReference = GetEdmTypeReference(edmTypeMap,
                                                                        procedure.ReturnType,
                                                                        procedure.ReturnType != null && procedure.OptionalReturn);
                IEdmExpression     expression     = GetEdmEntitySetExpression(edmNavigationSourceMap, procedure);
                IEdmPathExpression pathExpression = procedure.EntitySetPath != null
                    ? new EdmPathExpression(procedure.EntitySetPath)
                    : null;

                EdmOperationImport operationImport;

                switch (procedure.Kind)
                {
                case ProcedureKind.Action:
                    operationImport = CreateActionImport(procedure, container, returnReference, expression, pathExpression);
                    break;

                case ProcedureKind.Function:
                    operationImport = CreateFunctionImport((FunctionConfiguration)procedure, container, returnReference, expression, pathExpression);
                    break;

                case ProcedureKind.ServiceOperation:
                    Contract.Assert(false, "ServiceOperations are not supported.");
                    goto default;

                default:
                    Contract.Assert(false, "Unsupported ProcedureKind");
                    return;
                }

                EdmOperation operation = (EdmOperation)operationImport.Operation;
                if (procedure.IsBindable && procedure.Title != null & procedure.Title != procedure.Name)
                {
                    model.SetOperationTitleAnnotation(operation, new OperationTitleAnnotation(procedure.Title));
                }

                if (procedure.IsBindable &&
                    procedure.NavigationSource != null &&
                    edmNavigationSourceMap.ContainsKey(procedure.NavigationSource.Name))
                {
                    model.SetAnnotationValue(operation, new ReturnedEntitySetAnnotation(procedure.NavigationSource.Name));
                }

                AddProcedureParameters(operation, procedure, edmTypeMap);

                if (procedure.IsBindable)
                {
                    AddProcedureLinkBuilder(model, operation, procedure);
                    ValidateProcedureEntitySetPath(model, operationImport, procedure);
                }
                else
                {
                    container.AddElement(operationImport);
                }

                model.AddElement(operation);
            }
        }
예제 #19
0
        private static IEdmModel GetEdmModel()
        {
            EdmModel model = new EdmModel();

            // Order
            EdmEntityType order = new EdmEntityType("NS", "Order", null, false, true);

            order.AddKeys(order.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));

            // Customer
            EdmEntityType customer = new EdmEntityType("NS", "Customer");

            customer.AddKeys(customer.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
            customer.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            model.AddElement(customer);

            // VipCustomer
            EdmEntityType vipCustomer = new EdmEntityType("NS", "VipCustomer", customer);

            model.AddElement(vipCustomer);

            EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
            EdmEntitySet       orders    = container.AddEntitySet("Orders", order);
            EdmEntitySet       customers = container.AddEntitySet("Customers", customer);
            EdmSingleton       me        = container.AddSingleton("Me", customer);

            model.AddElement(container);

            EdmNavigationProperty ordersNavProp = customer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "Orders",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = order
            });

            customers.AddNavigationTarget(ordersNavProp, orders);
            me.AddNavigationTarget(ordersNavProp, orders);

            EdmNavigationProperty orderNavProp = customer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "Order",
                TargetMultiplicity = EdmMultiplicity.One,
                Target             = order
            });

            customers.AddNavigationTarget(orderNavProp, orders);
            me.AddNavigationTarget(orderNavProp, orders);

            EdmNavigationProperty subOrdersNavProp = customer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "SubOrders",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = order
            });

            customers.AddNavigationTarget(subOrdersNavProp, orders, new EdmPathExpression("NS.VipCustomer/SubOrders"));
            me.AddNavigationTarget(subOrdersNavProp, orders, new EdmPathExpression("NS.VipCustomer/SubOrders"));


            EdmNavigationProperty subOrderNavProp = customer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "SubOrder",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = order
            });

            customers.AddNavigationTarget(subOrderNavProp, orders, new EdmPathExpression("NS.VipCustomer/SubOrder"));
            me.AddNavigationTarget(subOrderNavProp, orders, new EdmPathExpression("NS.VipCustomer/SubOrder"));

            return(model);
        }
        /// <summary>
        /// Get EdmModel
        /// </summary>
        /// <returns><see cref="IEdmModel"/></returns>
        public virtual IEdmModel GetEdmModel()
        {
            var serviceContext = Dependencies.GetServiceContext();
            var website        = Dependencies.GetWebsite();
            var model          = new EdmModel();
            var container      = new EdmEntityContainer(NamespaceName, ContainerName);

            model.AddElement(container);
            model.SetIsDefaultEntityContainer(container, true);

            var entitylists = GetEntityLists(website);

            if (!entitylists.Any())
            {
                return(model);
            }

            var entityReferenceType = new EdmComplexType(NamespaceName, "EntityReference");

            entityReferenceType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Guid);
            entityReferenceType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);

            var picklistType = new EdmComplexType(NamespaceName, "OptionSet");

            picklistType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            picklistType.AddStructuralProperty("Value", EdmPrimitiveTypeKind.Int32);

            model.AddElement(entityReferenceType);
            model.AddElement(picklistType);

            var entitySetNames = new List <string>();

            foreach (var entitylist in entitylists)
            {
                var entityListId             = entitylist.GetAttributeValue <Guid>("adx_entitylistid");
                var entityListEntityName     = entitylist.GetAttributeValue <string>("adx_entityname");
                var entityListEntityTypeName = entitylist.GetAttributeValue <string>("adx_odata_entitytypename");
                var entityListEntitySetName  = entitylist.GetAttributeValue <string>("adx_odata_entitysetname");
                var entityTypeName           = string.IsNullOrWhiteSpace(entityListEntityTypeName) ? entityListEntityName : entityListEntityTypeName;
                var entitySetName            = string.IsNullOrWhiteSpace(entityListEntitySetName) ? entityListEntityName : entityListEntitySetName;
                var entityPermissionsEnabled = entitylist.GetAttributeValue <bool>("adx_entitypermissionsenabled");
                if (entitySetNames.Contains(entitySetName))
                {
                    ADXTrace.Instance.TraceError(TraceCategory.Application, string.Format(string.Format("An Entity Set has already been defined with the name '{0}'. Entity Set could not added to the model. You must not have multiple Entity List records with OData enabled and the same Entity Name specified, otherwise specifiy a unique Entity Set Name and Entity Type Name in the Entity List's OData Settings in CRM.", entitySetName)));
                    continue;
                }
                entitySetNames.Add(entitySetName);
                var entityType   = new EdmEntityType(NamespaceName, entityTypeName);
                var viewIdString = entitylist.GetAttributeValue <string>("adx_odata_view");

                if (string.IsNullOrWhiteSpace(viewIdString))
                {
                    continue;
                }

                Guid viewId;

                Guid.TryParse(viewIdString, out viewId);

                var savedQuery = GetSavedQuery(viewId);

                var view = new SavedQueryView(serviceContext, savedQuery, LanguageCode);

                var columns = view.Columns;

                var key = entityType.AddStructuralProperty(view.PrimaryKeyLogicalName, EdmPrimitiveTypeKind.Guid);
                entityType.AddKeys(key);

                foreach (var column in columns)
                {
                    var attributeMetadata = column.Metadata;
                    var propertyName      = column.LogicalName;
                    if (propertyName.Contains('.'))
                    {
                        propertyName = string.Format("{0}-{1}", column.Metadata.EntityLogicalName, column.Metadata.LogicalName);
                    }
                    var edmPrimitiveTypeKind = MetadataHelpers.GetEdmPrimitiveTypeKindFromAttributeMetadata(attributeMetadata);
                    if (edmPrimitiveTypeKind != null)
                    {
                        entityType.AddStructuralProperty(propertyName, edmPrimitiveTypeKind.GetValueOrDefault(EdmPrimitiveTypeKind.None));
                    }
                    else
                    {
                        switch (attributeMetadata.AttributeType)
                        {
                        case AttributeTypeCode.Customer:
                        case AttributeTypeCode.Lookup:
                        case AttributeTypeCode.Owner:
                            entityType.AddStructuralProperty(propertyName, new EdmComplexTypeReference(entityReferenceType, true));
                            break;

                        case AttributeTypeCode.Picklist:
                        case AttributeTypeCode.State:
                        case AttributeTypeCode.Status:
                            entityType.AddStructuralProperty(propertyName, new EdmComplexTypeReference(picklistType, true));
                            break;
                        }
                    }
                }

                entityType.AddProperty(new EdmStructuralProperty(entityType, "list-id", EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.String, true), entityListId.ToString(), EdmConcurrencyMode.None));
                entityType.AddProperty(new EdmStructuralProperty(entityType, "view-id", EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.String, true), viewId.ToString(), EdmConcurrencyMode.None));
                entityType.AddProperty(new EdmStructuralProperty(entityType, "entity-permissions-enabled", EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.String, true), entityPermissionsEnabled.ToString(), EdmConcurrencyMode.None));

                model.AddElement(entityType);
                container.AddEntitySet(entitySetName, entityType);
            }

            return(model);
        }
        public void AssociationLinkOnNavigationLinkTest()
        {
            EdmModel model = new EdmModel();

            var container = new EdmEntityContainer("TestModel", "Default");

            model.AddElement(container);

            var edmEntityTypeOrderType = new EdmEntityType("TestModel", "OrderType");

            model.AddElement(edmEntityTypeOrderType);

            var edmEntityTypeCustomerType = new EdmEntityType("TestModel", "CustomerType");
            var edmNavigationPropertyAssociationLinkOne = edmEntityTypeCustomerType.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo {
                Name = "NavProp1", Target = edmEntityTypeOrderType, TargetMultiplicity = EdmMultiplicity.One
            });
            var edmNavigationPropertyAssociationLinkTwo = edmEntityTypeCustomerType.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo {
                Name = "NavProp2", Target = edmEntityTypeOrderType, TargetMultiplicity = EdmMultiplicity.Many
            });

            model.AddElement(edmEntityTypeCustomerType);

            var customerSet = container.AddEntitySet("Customers", edmEntityTypeCustomerType);
            var orderSet    = container.AddEntitySet("Orders", edmEntityTypeOrderType);

            customerSet.AddNavigationTarget(edmNavigationPropertyAssociationLinkOne, orderSet);
            customerSet.AddNavigationTarget(edmNavigationPropertyAssociationLinkTwo, orderSet);

            var testCases = new[]
            {
                // Both nav link URL and association link URL
                new {
                    NavigationLink = new ODataNavigationLink()
                    {
                        Name = "NavProp1", IsCollection = false, Url = new Uri("http://odata.org/navlink"), AssociationLinkUrl = new Uri("http://odata.org/assoclink")
                    },
                    PropertyName = "NavProp1",
                    Atom         = BuildXmlNavigationLink("NavProp1", "application/atom+xml;type=entry", "http://odata.org/navlink"),
                    JsonLight    =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("NavProp1", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("NavProp1", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/assoclink\""
                },
                // Just nav link URL
                new {
                    NavigationLink = new ODataNavigationLink()
                    {
                        Name = "NavProp1", IsCollection = false, Url = new Uri("http://odata.org/navlink"), AssociationLinkUrl = null
                    },
                    PropertyName = "NavProp1",
                    Atom         = BuildXmlNavigationLink("NavProp1", "application/atom+xml;type=entry", "http://odata.org/navlink"),
                    JsonLight    = "\"" + JsonLightUtils.GetPropertyAnnotationName("NavProp1", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navlink\""
                },
                // Just association link URL
                new {
                    NavigationLink = new ODataNavigationLink()
                    {
                        Name = "NavProp1", IsCollection = false, Url = null, AssociationLinkUrl = new Uri("http://odata.org/assoclink")
                    },
                    PropertyName = "NavProp1",
                    Atom         = (string)null,
                    JsonLight    = "\"" + JsonLightUtils.GetPropertyAnnotationName("NavProp1", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/assoclink\""
                },
                // Navigation link with both URLs null
                new {
                    NavigationLink = new ODataNavigationLink()
                    {
                        Name = "NavProp1", IsCollection = false, Url = null, AssociationLinkUrl = null
                    },
                    PropertyName = "NavProp1",
                    Atom         = (string)null,
                    JsonLight    = string.Empty
                }
            };

            IEnumerable <PayloadWriterTestDescriptor <ODataItem> > testDescriptors = testCases.Select(testCase =>
            {
                ODataEntry entry = ObjectModelUtils.CreateDefaultEntry();
                entry.TypeName   = "TestModel.CustomerType";
                return(new PayloadWriterTestDescriptor <ODataItem>(
                           this.Settings,
                           new ODataItem[] { entry, testCase.NavigationLink, null },
                           (testConfiguration) =>
                {
                    if (testConfiguration.Format == ODataFormat.Atom)
                    {
                        return new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                        {
                            Xml = "<Links>" + testCase.Atom + "</Links>",
                            FragmentExtractor = (result) =>
                            {
                                var links = result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName)
                                            .Where(l => l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value.StartsWith(
                                                       TestAtomConstants.ODataNavigationPropertiesAssociationLinkRelationPrefix) ||
                                                   l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value.StartsWith(
                                                       TestAtomConstants.ODataNavigationPropertiesRelatedLinkRelationPrefix));
                                result = new XElement("Ref", links);
                                if (result.FirstNode == null)
                                {
                                    result.Add("");
                                }

                                return result;
                            },
                            ExpectedException2 = testCase.Atom == null ? ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyUrl", testCase.PropertyName) : null
                        };
                    }
                    else if (testConfiguration.Format == ODataFormat.Json)
                    {
                        return new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                        {
                            Json = string.Join(
                                "$(NL)",
                                "{",
                                testCase.JsonLight,
                                "}"),
                            FragmentExtractor = (result) =>
                            {
                                var links = result.Object().GetPropertyAnnotations(testCase.PropertyName).ToList();
                                var jsonResult = new JsonObject();
                                links.ForEach(l =>
                                {
                                    // NOTE we remove all annoatations here and in particular the text annotations to be able to easily compare
                                    //      against the expected results. This however means that we do not distinguish between the indented and non-indented case here.
                                    l.RemoveAllAnnotations(true);
                                    jsonResult.Add(l);
                                });
                                return jsonResult;
                            }
                        };
                    }
                    else
                    {
                        this.Settings.Assert.Fail("Unknown format '{0}'.", testConfiguration.Format);
                        return null;
                    }
                })
                {
                    Model = model,
                    PayloadEdmElementContainer = customerSet
                });
            });

            // With and without model
            testDescriptors = testDescriptors.SelectMany(td =>
                                                         new[]
            {
                td,
                new PayloadWriterTestDescriptor <ODataItem>(td)
                {
                    Model = null,
                    PayloadEdmElementContainer = null
                }
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors.PayloadCases(WriterPayloads.EntryPayloads),
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurationsWithIndent.Where(testConfiguration => !testConfiguration.IsRequest),
                (testDescriptor, testConfiguration) =>
            {
                testConfiguration = testConfiguration.Clone();
                testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                if (testDescriptor.Model == null && testConfiguration.Format == ODataFormat.Json)
                {
                    return;
                }

                if (testDescriptor.IsGeneratedPayload && testDescriptor.Model != null)
                {
                    return;
                }

                TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor, testConfiguration, this.Assert, this.Logger);
            });
        }
        public ODataJsonLightReaderEnumIntegrationTests()
        {
            EdmModel tmpModel = new EdmModel();

            // enum without flags
            var enumType = new EdmEnumType("NS", "Color");
            var red      = new EdmEnumMember(enumType, "Red", new EdmIntegerConstant(1));

            enumType.AddMember(red);
            enumType.AddMember("Green", new EdmIntegerConstant(2));
            enumType.AddMember("Blue", new EdmIntegerConstant(3));
            tmpModel.AddElement(enumType);

            // enum with flags
            var enumFlagsType = new EdmEnumType("NS", "ColorFlags", isFlags: true);

            enumFlagsType.AddMember("Red", new EdmIntegerConstant(1));
            enumFlagsType.AddMember("Green", new EdmIntegerConstant(2));
            enumFlagsType.AddMember("Blue", new EdmIntegerConstant(4));
            tmpModel.AddElement(enumFlagsType);

            this.entityType = new EdmEntityType("NS", "MyEntityType", isAbstract: false, isOpen: true, baseType: null);
            EdmStructuralProperty floatId = new EdmStructuralProperty(this.entityType, "FloatId", EdmCoreModel.Instance.GetSingle(false));

            this.entityType.AddKeys(floatId);
            this.entityType.AddProperty(floatId);
            var enumTypeReference = new EdmEnumTypeReference(enumType, true);

            this.entityType.AddProperty(new EdmStructuralProperty(this.entityType, "Color", enumTypeReference));
            var enumFlagsTypeReference = new EdmEnumTypeReference(enumFlagsType, false);

            this.entityType.AddProperty(new EdmStructuralProperty(this.entityType, "ColorFlags", enumFlagsTypeReference));

            // enum in complex type
            EdmComplexType myComplexType = new EdmComplexType("NS", "MyComplexType");

            myComplexType.AddProperty(new EdmStructuralProperty(myComplexType, "MyColorFlags", enumFlagsTypeReference));
            myComplexType.AddProperty(new EdmStructuralProperty(myComplexType, "Height", EdmCoreModel.Instance.GetDouble(false)));
            tmpModel.AddElement(myComplexType);
            this.entityType.AddProperty(new EdmStructuralProperty(this.entityType, "MyComplexType", new EdmComplexTypeReference(myComplexType, true)));

            // enum in derived complex type
            EdmComplexType myDerivedComplexType = new EdmComplexType("NS", "MyDerivedComplexType", myComplexType, false);

            myDerivedComplexType.AddProperty(new EdmStructuralProperty(myDerivedComplexType, "MyDerivedColorFlags", new EdmEnumTypeReference(enumFlagsType, false)));
            tmpModel.AddElement(myDerivedComplexType);

            // enum in collection type
            EdmCollectionType myCollectionType = new EdmCollectionType(enumFlagsTypeReference);

            this.entityType.AddProperty(new EdmStructuralProperty(this.entityType, "MyCollectionType", new EdmCollectionTypeReference(myCollectionType)));

            tmpModel.AddElement(this.entityType);

            var defaultContainer = new EdmEntityContainer("NS", "DefaultContainer_sub");

            this.entitySet = new EdmEntitySet(defaultContainer, "MySet", this.entityType);
            defaultContainer.AddEntitySet(this.entitySet.Name, this.entityType);
            tmpModel.AddElement(defaultContainer);

            this.userModel = TestUtils.WrapReferencedModelsToMainModel("NS", "DefaultContainer", tmpModel);
        }
        public void AssociationLinkMetadataValidationTest()
        {
            EdmModel model = new EdmModel();

            var container = new EdmEntityContainer("TestModel", "Default");

            model.AddElement(container);

            var edmEntityTypeOrderType = new EdmEntityType("TestModel", "OrderType");

            model.AddElement(edmEntityTypeOrderType);

            var edmEntityTypeCustomerType = new EdmEntityType("TestModel", "CustomerType");

            edmEntityTypeCustomerType.AddKeys(new EdmStructuralProperty(edmEntityTypeCustomerType, "ID", EdmCoreModel.Instance.GetInt32(false)));
            edmEntityTypeCustomerType.AddStructuralProperty("PrimitiveProperty", EdmCoreModel.Instance.GetString(true));
            var edmNavigationPropertyAssociationLinkOne = edmEntityTypeCustomerType.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo {
                Name = "Orders", Target = edmEntityTypeOrderType, TargetMultiplicity = EdmMultiplicity.Many
            });
            var edmNavigationPropertyAssociationLinkTwo = edmEntityTypeCustomerType.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo {
                Name = "BestFriend", Target = edmEntityTypeCustomerType, TargetMultiplicity = EdmMultiplicity.One
            });

            model.AddElement(edmEntityTypeCustomerType);

            var edmEntityTypeOpenCustomerType = new EdmEntityType("TestModel", "OpenCustomerType", edmEntityTypeCustomerType, isAbstract: false, isOpen: true);

            model.AddElement(edmEntityTypeOpenCustomerType);

            var customerSet = container.AddEntitySet("Customers", edmEntityTypeCustomerType);
            var orderSet    = container.AddEntitySet("Orders", edmEntityTypeOrderType);

            customerSet.AddNavigationTarget(edmNavigationPropertyAssociationLinkOne, orderSet);
            customerSet.AddNavigationTarget(edmNavigationPropertyAssociationLinkTwo, customerSet);

            Uri associationLinkUrl = new Uri("http://odata.org/associationlink");

            var testCases = new[]
            {
                // Valid collection
                new
                {
                    TypeName          = "TestModel.CustomerType",
                    NavigationLink    = ObjectModelUtils.CreateDefaultCollectionLink("Orders"),
                    ExpectedException = (ExpectedException)null,
                },
                // Valid singleton
                new
                {
                    TypeName          = "TestModel.CustomerType",
                    NavigationLink    = ObjectModelUtils.CreateDefaultSingletonLink("BestFriend"),
                    ExpectedException = (ExpectedException)null,
                },
                // Undeclared on closed type
                new
                {
                    TypeName          = "TestModel.CustomerType",
                    NavigationLink    = ObjectModelUtils.CreateDefaultCollectionLink("NonExistant"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_PropertyDoesNotExistOnType", "NonExistant", "TestModel.CustomerType"),
                },
                // Undeclared on open type
                new
                {
                    TypeName          = "TestModel.OpenCustomerType",
                    NavigationLink    = ObjectModelUtils.CreateDefaultCollectionLink("NonExistant"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_OpenNavigationProperty", "NonExistant", "TestModel.OpenCustomerType"),
                },
                // Declared but of wrong kind
                new
                {
                    TypeName          = "TestModel.CustomerType",
                    NavigationLink    = ObjectModelUtils.CreateDefaultSingletonLink("PrimitiveProperty"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_NavigationPropertyExpected", "PrimitiveProperty", "TestModel.CustomerType", "Structural"),
                },
            };

            var testDescriptors = testCases.Select(testCase =>
            {
                ODataEntry entry = ObjectModelUtils.CreateDefaultEntry();
                entry.TypeName   = testCase.TypeName;
                ODataNavigationLink navigationLink = testCase.NavigationLink;
                navigationLink.AssociationLinkUrl  = associationLinkUrl;

                return(new PayloadWriterTestDescriptor <ODataItem>(
                           this.Settings,
                           new ODataItem[] { entry, navigationLink },
                           tc => tc.Format == ODataFormat.Atom ?
                           (WriterTestExpectedResults) new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                {
                    ExpectedException2 = testCase.ExpectedException
                } :
                           (WriterTestExpectedResults) new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                {
                    ExpectedException2 = testCase.ExpectedException
                })
                {
                    Model = model,
                    PayloadEdmElementContainer = customerSet
                });
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.WriterTestConfigurationProvider.AtomFormatConfigurations
                .Where(testConfiguration => !testConfiguration.IsRequest),
                (testDescriptor, testConfiguration) =>
            {
                testConfiguration = testConfiguration.Clone();
                testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor, testConfiguration, this.Assert, this.Logger);
            });
        }
예제 #24
0
        public EdmModel BuildEdmModel()
        {
            foreach (EntityTypeInfo typeInfo in _entityTypes.Values)
            {
                typeInfo.BuildProperties(_entityTypes, _enumTypes, _complexTypes);
            }

            foreach (EntityTypeInfo typeInfo in _entityTypes.Values)
            {
                foreach (FKeyInfo fkeyInfo in typeInfo.NavigationClrProperties)
                {
                    fkeyInfo.EdmNavigationProperty = CreateNavigationProperty(fkeyInfo);
                }
            }

            var edmModel  = new EdmModel();
            var container = new EdmEntityContainer("Default", "Container");

            edmModel.AddElements(_enumTypes.Values);
            foreach (KeyValuePair <Type, EdmEnumType> enumType in _enumTypes)
            {
                edmModel.SetAnnotationValue(enumType.Value, new OeClrTypeAnnotation(enumType.Key));
            }

            edmModel.AddElements(_complexTypes.Values);
            foreach (KeyValuePair <Type, EdmComplexType> complexType in _complexTypes)
            {
                edmModel.SetAnnotationValue(complexType.Value, new OeClrTypeAnnotation(complexType.Key));
            }

            var entitySets = new Dictionary <IEdmEntityType, EdmEntitySet>(_entityTypes.Count);

            foreach (EntityTypeInfo typeInfo in _entityTypes.Values)
            {
                edmModel.AddElement(typeInfo.EdmType);
                edmModel.SetAnnotationValue(typeInfo.EdmType, new OeClrTypeAnnotation(typeInfo.ClrType));
                entitySets.Add(typeInfo.EdmType, container.AddEntitySet(typeInfo.EntitySetName, typeInfo.EdmType));
            }

            foreach (EntityTypeInfo typeInfo in _entityTypes.Values)
            {
                foreach (FKeyInfo fkeyInfo in typeInfo.NavigationClrProperties)
                {
                    EdmEntitySet principal = entitySets[fkeyInfo.PrincipalInfo.EdmType];
                    EdmEntitySet dependent = entitySets[fkeyInfo.DependentInfo.EdmType];
                    dependent.AddNavigationTarget(fkeyInfo.EdmNavigationProperty, principal);

                    if (fkeyInfo.EdmNavigationProperty.Partner != null)
                    {
                        principal.AddNavigationTarget(fkeyInfo.EdmNavigationProperty.Partner, dependent);
                    }
                }
            }


            foreach (OeOperationConfiguration operationConfiguration in _operationConfigurations)
            {
                if (operationConfiguration.IsFunction)
                {
                    EdmFunction edmFunction = BuildFunction(operationConfiguration);
                    if (edmFunction != null)
                    {
                        container.AddFunctionImport(edmFunction);
                    }
                }
                else
                {
                    EdmAction edmAction = BuildAction(operationConfiguration);
                    if (edmAction != null)
                    {
                        container.AddActionImport(edmAction);
                    }
                }
            }

            edmModel.AddElement(container);
            return(edmModel);
        }
        public void AssociationLinkTest()
        {
            string associationLinkName1 = "AssociationLinkOne";
            string linkUrl1             = "http://odata.org/associationlink";
            Uri    linkUrlUri1          = new Uri(linkUrl1);
            string associationLinkName2 = "AssociationLinkTwo";
            string linkUrl2             = "http://odata.org/associationlink2";
            Uri    linkUrlUri2          = new Uri(linkUrl2);

            EdmModel model = new EdmModel();

            var edmEntityTypeOrderType = new EdmEntityType("TestModel", "OrderType");

            model.AddElement(edmEntityTypeOrderType);

            var edmEntityTypeCustomerType = new EdmEntityType("TestModel", "CustomerType");
            var edmNavigationPropertyAssociationLinkOne = edmEntityTypeCustomerType.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo {
                Name = associationLinkName1, Target = edmEntityTypeOrderType, TargetMultiplicity = EdmMultiplicity.One
            });
            var edmNavigationPropertyAssociationLinkTwo = edmEntityTypeCustomerType.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo {
                Name = associationLinkName2, Target = edmEntityTypeOrderType, TargetMultiplicity = EdmMultiplicity.Many
            });

            model.AddElement(edmEntityTypeCustomerType);

            var container = new EdmEntityContainer("TestModel", "Default");

            model.AddElement(container);

            var customerSet = container.AddEntitySet("Customers", edmEntityTypeCustomerType);
            var orderSet    = container.AddEntitySet("Orders", edmEntityTypeOrderType);

            customerSet.AddNavigationTarget(edmNavigationPropertyAssociationLinkOne, orderSet);
            customerSet.AddNavigationTarget(edmNavigationPropertyAssociationLinkTwo, orderSet);

            var testCases = new[]
            {
                new {
                    NavigationLink = ObjectModelUtils.CreateDefaultNavigationLink(associationLinkName1, linkUrlUri1),
                    Atom           = BuildXmlAssociationLink(associationLinkName1, "application/xml", linkUrl1),
                    JsonLight      = (string)null,
                },
                new {
                    NavigationLink = ObjectModelUtils.CreateDefaultNavigationLink(associationLinkName2, linkUrlUri2),
                    Atom           = BuildXmlAssociationLink(associationLinkName2, "application/xml", linkUrl2),
                    JsonLight      = (string)null
                },
            };

            var testCasesWithMultipleLinks = testCases.Variations()
                                             .Select(tcs =>
                                                     new
            {
                NavigationLinks = tcs.Select(tc => tc.NavigationLink),
                Atom            = string.Concat(tcs.Select(tc => tc.Atom)),
                JsonLight       = string.Join(",", tcs.Where(tc => tc.JsonLight != null).Select(tc => tc.JsonLight))
            });

            var testDescriptors = testCasesWithMultipleLinks.Select(testCase =>
            {
                ODataEntry entry       = ObjectModelUtils.CreateDefaultEntry();
                entry.TypeName         = "TestModel.CustomerType";
                List <ODataItem> items = new ODataItem[] { entry }.ToList();
                foreach (var navLink in testCase.NavigationLinks)
                {
                    items.Add(navLink);
                    items.Add(null);
                }

                return(new PayloadWriterTestDescriptor <ODataItem>(
                           this.Settings,
                           items,
                           (testConfiguration) =>
                {
                    var firstAssocLink = testCase.NavigationLinks == null ? null : testCase.NavigationLinks.FirstOrDefault();
                    if (testConfiguration.Format == ODataFormat.Atom)
                    {
                        return new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                        {
                            Xml = "<AssociationLinks>" + testCase.Atom + "</AssociationLinks>",
                            FragmentExtractor = (result) =>
                            {
                                var links = result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName)
                                            .Where(l => l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value.StartsWith(
                                                       TestAtomConstants.ODataNavigationPropertiesAssociationLinkRelationPrefix));
                                result = new XElement("AssociationLinks", links);
                                if (result.FirstNode == null)
                                {
                                    result.Add("");
                                }

                                return result;
                            },
                            ExpectedException2 = testConfiguration.IsRequest && firstAssocLink != null
                                    ? ODataExpectedExceptions.ODataException("ODataWriterCore_DeferredLinkInRequest")
                                    : null
                        };
                    }
                    else if (testConfiguration.Format == ODataFormat.Json)
                    {
                        return new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                        {
                            Json = string.Join(
                                "$(NL)",
                                "{",
                                testCase.JsonLight,
                                "}"),
                            FragmentExtractor = (result) =>
                            {
                                var associationLinks = result.Object().GetAnnotationsWithName("@" + JsonLightConstants.ODataAssociationLinkUrlAnnotationName).ToList();
                                var jsonResult = new JsonObject();
                                associationLinks.ForEach(l =>
                                {
                                    // NOTE we remove all annoatations here and in particular the text annotations to be able to easily compare
                                    //      against the expected results. This however means that we do not distinguish between the indented and non-indented case here.
                                    l.RemoveAllAnnotations(true);
                                    jsonResult.Add(l);
                                });
                                return jsonResult;
                            },
                        };
                    }
                    else
                    {
                        this.Settings.Assert.Fail("Unknown format '{0}'.", testConfiguration.Format);
                        return null;
                    }
                })
                {
                    Model = model,
                    PayloadEdmElementContainer = customerSet
                });
            });

            // With and without model
            testDescriptors = testDescriptors.SelectMany(td =>
                                                         new[]
            {
                td,
                new PayloadWriterTestDescriptor <ODataItem>(td)
                {
                    Model = null,
                    PayloadEdmElementContainer = null
                }
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors.PayloadCases(WriterPayloads.EntryPayloads),
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurationsWithIndent,
                (testDescriptor, testConfiguration) =>
            {
                testConfiguration = testConfiguration.Clone();
                testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                if (testDescriptor.Model == null && testConfiguration.Format == ODataFormat.Json)
                {
                    return;
                }

                if (testDescriptor.IsGeneratedPayload && testDescriptor.Model != null)
                {
                    return;
                }

                TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor, testConfiguration, this.Assert, this.Logger);
            });
        }
        public static IEdmModel SimpleCustomerOrderModel()
        {
            var model        = new EdmModel();
            var customerType = new EdmEntityType("Default", "Customer");

            customerType.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32);
            customerType.AddStructuralProperty("FirstName", EdmPrimitiveTypeKind.String);
            customerType.AddStructuralProperty("LastName", EdmPrimitiveTypeKind.String);
            IEdmTypeReference primitiveTypeReference = EdmCoreModel.Instance.GetPrimitive(
                EdmPrimitiveTypeKind.String,
                isNullable: true);

            customerType.AddStructuralProperty(
                "City",
                primitiveTypeReference,
                defaultValue: null,
                concurrencyMode: EdmConcurrencyMode.Fixed);
            model.AddElement(customerType);

            var specialCustomerType = new EdmEntityType("Default", "SpecialCustomer", customerType);

            model.AddElement(specialCustomerType);

            var orderType = new EdmEntityType("Default", "Order");

            orderType.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32);
            orderType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            orderType.AddStructuralProperty("Shipment", EdmPrimitiveTypeKind.String);
            model.AddElement(orderType);

            var specialOrderType = new EdmEntityType("Default", "SpecialOrder", orderType);

            model.AddElement(specialOrderType);

            var addressType = new EdmComplexType("Default", "Address");

            addressType.AddStructuralProperty("Street", EdmPrimitiveTypeKind.String);
            addressType.AddStructuralProperty("City", EdmPrimitiveTypeKind.String);
            addressType.AddStructuralProperty("State", EdmPrimitiveTypeKind.String);
            addressType.AddStructuralProperty("Country", EdmPrimitiveTypeKind.String);
            addressType.AddStructuralProperty("ZipCode", EdmPrimitiveTypeKind.String);
            model.AddElement(addressType);

            // add a derived complex type "UsAddress"
            var usAddressType = new EdmComplexType("Default", "UsAddress", addressType);

            usAddressType.AddStructuralProperty("UsProp", EdmPrimitiveTypeKind.String);
            model.AddElement(usAddressType);

            // add a derived complex type "CnAddress"
            var cnAddressType = new EdmComplexType("Default", "CnAddress", addressType);

            cnAddressType.AddStructuralProperty("CnProp", EdmPrimitiveTypeKind.Guid);
            model.AddElement(cnAddressType);

            // Add navigations
            customerType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo()
            {
                Name = "Orders", Target = orderType, TargetMultiplicity = EdmMultiplicity.Many
            });
            orderType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo()
            {
                Name = "Customer", Target = customerType, TargetMultiplicity = EdmMultiplicity.One
            });
            specialCustomerType.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name               = "SpecialOrders",
                Target             = specialOrderType,
                TargetMultiplicity = EdmMultiplicity.Many
            });
            orderType.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name               = "SpecialCustomer",
                Target             = specialCustomerType,
                TargetMultiplicity = EdmMultiplicity.One
            });

            // Add Entity set
            var container   = new EdmEntityContainer("Default", "Container");
            var customerSet = container.AddEntitySet("Customers", customerType);
            var orderSet    = container.AddEntitySet("Orders", orderType);

            customerSet.AddNavigationTarget(customerType.NavigationProperties().Single(np => np.Name == "Orders"), orderSet);
            customerSet.AddNavigationTarget(
                specialCustomerType.NavigationProperties().Single(np => np.Name == "SpecialOrders"),
                orderSet);
            orderSet.AddNavigationTarget(orderType.NavigationProperties().Single(np => np.Name == "Customer"), customerSet);
            orderSet.AddNavigationTarget(
                specialOrderType.NavigationProperties().Single(np => np.Name == "SpecialCustomer"),
                customerSet);

            NavigationSourceLinkBuilderAnnotation linkAnnotation = new MockNavigationSourceLinkBuilderAnnotation();

            model.SetNavigationSourceLinkBuilder(customerSet, linkAnnotation);
            model.SetNavigationSourceLinkBuilder(orderSet, linkAnnotation);

            model.AddElement(container);
            return(model);
        }
예제 #27
0
        private static IEdmModel CreateEdmModel()
        {
            var model = new EdmModel();

            var coreDescription = CoreVocabularyModel.DescriptionTerm;

            var enumType = new EdmEnumType("DefaultNs", "Color");
            var blue     = enumType.AddMember("Blue", new EdmEnumMemberValue(0));

            enumType.AddMember("White", new EdmEnumMemberValue(1));
            model.AddElement(enumType);

            var annotation = new EdmVocabularyAnnotation(enumType, coreDescription, new EdmStringConstant("Enum type 'Color' description."));

            model.AddVocabularyAnnotation(annotation);

            var person   = new EdmEntityType("DefaultNs", "Person");
            var entityId = person.AddStructuralProperty("UserName", EdmCoreModel.Instance.GetString(false));

            person.AddKeys(entityId);

            var city   = new EdmEntityType("DefaultNs", "City");
            var cityId = city.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(false));

            city.AddKeys(cityId);

            var countryOrRegion = new EdmEntityType("DefaultNs", "CountryOrRegion");
            var countryId       = countryOrRegion.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(false));

            countryOrRegion.AddKeys(countryId);

            var complex = new EdmComplexType("DefaultNs", "Address");

            complex.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false));
            var navP = complex.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo()
            {
                Name               = "City",
                Target             = city,
                TargetMultiplicity = EdmMultiplicity.One,
            });

            var derivedComplex = new EdmComplexType("DefaultNs", "WorkAddress", complex);
            var navP2          = derivedComplex.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo()
            {
                Name               = "CountryOrRegion",
                Target             = countryOrRegion,
                TargetMultiplicity = EdmMultiplicity.One,
            });

            person.AddStructuralProperty("HomeAddress", new EdmComplexTypeReference(complex, false));
            person.AddStructuralProperty("WorkAddress", new EdmComplexTypeReference(complex, false));
            person.AddStructuralProperty("Addresses",
                                         new EdmCollectionTypeReference(new EdmCollectionType(new EdmComplexTypeReference(complex, false))));

            model.AddElement(person);
            model.AddElement(city);
            model.AddElement(countryOrRegion);
            model.AddElement(complex);
            model.AddElement(derivedComplex);

            var entityContainer = new EdmEntityContainer("DefaultNs", "Container");

            model.AddElement(entityContainer);
            EdmSingleton me                 = new EdmSingleton(entityContainer, "Me", person);
            EdmEntitySet people             = new EdmEntitySet(entityContainer, "People", person);
            EdmEntitySet cities             = new EdmEntitySet(entityContainer, "City", city);
            EdmEntitySet countriesOrRegions = new EdmEntitySet(entityContainer, "CountryOrRegion", countryOrRegion);

            people.AddNavigationTarget(navP, cities, new EdmPathExpression("HomeAddress/City"));
            people.AddNavigationTarget(navP, cities, new EdmPathExpression("Addresses/City"));
            people.AddNavigationTarget(navP2, countriesOrRegions,
                                       new EdmPathExpression("WorkAddress/DefaultNs.WorkAddress/CountryOrRegion"));
            entityContainer.AddElement(people);
            entityContainer.AddElement(cities);
            entityContainer.AddElement(countriesOrRegions);
            entityContainer.AddElement(me);

            annotation = new EdmVocabularyAnnotation(people, coreDescription, new EdmStringConstant("People's description."));
            model.AddVocabularyAnnotation(annotation);

            var coreLongDescription = CoreVocabularyModel.LongDescriptionTerm;

            annotation = new EdmVocabularyAnnotation(people, coreLongDescription, new EdmStringConstant("People's Long description."));
            model.AddVocabularyAnnotation(annotation);

            return(model);
        }
예제 #28
0
        public static IEdmModel GetEdmModel1()
        {
            EdmModel model = new EdmModel();

            // Complex Type
            EdmComplexType address = new EdmComplexType("WebApiDocNS", "Address");

            address.AddStructuralProperty("Country", EdmPrimitiveTypeKind.String);
            address.AddStructuralProperty("City", EdmPrimitiveTypeKind.String);
            model.AddElement(address);

            EdmComplexType subAddress = new EdmComplexType("WebApiDocNS", "SubAddress", address);

            subAddress.AddStructuralProperty("Street", EdmPrimitiveTypeKind.String);
            model.AddElement(subAddress);

            // Enum type
            EdmEnumType color = new EdmEnumType("WebApiDocNS", "Color");

            color.AddMember(new EdmEnumMember(color, "Red", new EdmEnumMemberValue(0)));
            color.AddMember(new EdmEnumMember(color, "Blue", new EdmEnumMemberValue(1)));
            color.AddMember(new EdmEnumMember(color, "Green", new EdmEnumMemberValue(2)));
            model.AddElement(color);

            // Entity type
            EdmEntityType customer = new EdmEntityType("WebApiDocNS", "Customer");

            customer.AddKeys(customer.AddStructuralProperty("CustomerId", EdmPrimitiveTypeKind.Int32));
            customer.AddStructuralProperty("Location", new EdmComplexTypeReference(address, isNullable: true));
            model.AddElement(customer);

            EdmEntityType vipCustomer = new EdmEntityType("WebApiDocNS", "VipCustomer", customer);

            vipCustomer.AddStructuralProperty("FavoriteColor", new EdmEnumTypeReference(color, isNullable: false));
            model.AddElement(vipCustomer);

            EdmEntityType order = new EdmEntityType("WebApiDocNS", "Order");

            order.AddKeys(order.AddStructuralProperty("OrderId", EdmPrimitiveTypeKind.Int32));
            order.AddStructuralProperty("Token", EdmPrimitiveTypeKind.Guid);
            model.AddElement(order);

            EdmEntityContainer container = new EdmEntityContainer("WebApiDocNS", "Container");
            EdmEntitySet       customers = container.AddEntitySet("Customers", customer);
            EdmEntitySet       orders    = container.AddEntitySet("Orders", order);

            model.AddElement(container);

            // EdmSingleton mary = container.AddSingleton("Mary", customer);

            // navigation properties
            EdmNavigationProperty ordersNavProp = customer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "Orders",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = order
            });

            customers.AddNavigationTarget(ordersNavProp, orders);

            // function
            IEdmTypeReference stringType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.String, isNullable: false);
            IEdmTypeReference intType    = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Int32, isNullable: false);

            EdmFunction getFirstName = new EdmFunction("WebApiDocNS", "GetFirstName", stringType, isBound: true, entitySetPathExpression: null, isComposable: false);

            getFirstName.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(getFirstName);

            EdmFunction getNumber = new EdmFunction("WebApiDocNS", "GetOrderCount", intType, isBound: false, entitySetPathExpression: null, isComposable: false);

            model.AddElement(getNumber);
            container.AddFunctionImport("GetOrderCount", getNumber);

            // action
            EdmAction calculate = new EdmAction("WebApiDocNS", "CalculateOrderPrice", returnType: null, isBound: true, entitySetPathExpression: null);

            calculate.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(calculate);

            EdmAction change = new EdmAction("WebApiDocNS", "ChangeCustomerById", returnType: null, isBound: false, entitySetPathExpression: null);

            change.AddParameter("Id", intType);
            model.AddElement(change);
            container.AddActionImport("ChangeCustomerById", change);

            return(model);
        }
예제 #29
0
        private static IEdmModel CreateMultipleInheritanceEdmModel()
        {
            var model = new EdmModel();

            // enum type
            var colorEnumType = new EdmEnumType("NS", "Color");

            colorEnumType.AddMember("Blue", new EdmEnumMemberValue(0));
            colorEnumType.AddMember("While", new EdmEnumMemberValue(1));
            colorEnumType.AddMember("Red", new EdmEnumMemberValue(2));
            colorEnumType.AddMember("Yellow", new EdmEnumMemberValue(3));
            model.AddElement(colorEnumType);

            var oceanEnumType = new EdmEnumType("NS", "Ocean");

            oceanEnumType.AddMember("Atlantic", new EdmEnumMemberValue(0));
            oceanEnumType.AddMember("Pacific", new EdmEnumMemberValue(1));
            oceanEnumType.AddMember("India", new EdmEnumMemberValue(2));
            oceanEnumType.AddMember("Arctic", new EdmEnumMemberValue(3));
            model.AddElement(oceanEnumType);

            var continentEnumType = new EdmEnumType("NS", "Continent");

            continentEnumType.AddMember("Asia", new EdmEnumMemberValue(0));
            continentEnumType.AddMember("Europe", new EdmEnumMemberValue(1));
            continentEnumType.AddMember("Antarctica", new EdmEnumMemberValue(2));
            model.AddElement(continentEnumType);

            // top level entity type
            var zoo   = new EdmEntityType("NS", "Zoo");
            var zooId = zoo.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false));

            zoo.AddKeys(zooId);
            model.AddElement(zoo);

            // abstract entity type "Creature"
            var creature = new EdmEntityType("NS", "Creature", null, true, true);

            creature.AddKeys(creature.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false)));
            model.AddElement(creature);

            var animal = new EdmEntityType("NS", "Animal", creature, true, true);

            animal.AddStructuralProperty("Age", EdmCoreModel.Instance.GetInt32(false));
            model.AddElement(animal);

            var human = new EdmEntityType("NS", "Human", animal, false, true);

            human.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(false));
            model.AddElement(human);

            var horse = new EdmEntityType("NS", "Horse", animal, false, true);

            horse.AddStructuralProperty("Height", EdmCoreModel.Instance.GetDecimal(false));
            model.AddElement(horse);

            EdmNavigationPropertyInfo navInfo = new EdmNavigationPropertyInfo
            {
                Name               = "Creatures",
                Target             = creature,
                TargetMultiplicity = EdmMultiplicity.Many,
            };

            zoo.AddUnidirectionalNavigation(navInfo);

            // complex type
            var plant = new EdmComplexType("NS", "Plant", null, true, true);

            plant.AddStructuralProperty("Color", new EdmEnumTypeReference(colorEnumType, isNullable: false));
            model.AddElement(plant);

            // ocean plant
            var oceanPlant = new EdmComplexType("NS", "OceanPlant", plant, true, true);

            oceanPlant.AddStructuralProperty("Ocean", new EdmEnumTypeReference(oceanEnumType, isNullable: false));
            model.AddElement(oceanPlant);

            var kelp = new EdmComplexType("NS", "Kelp", oceanPlant, false, true);

            kelp.AddStructuralProperty("Length", EdmCoreModel.Instance.GetDouble(false));
            model.AddElement(kelp);

            // land plant
            var landPlant = new EdmComplexType("NS", "LandPlant", plant, true, true);

            landPlant.AddStructuralProperty("Continent", new EdmEnumTypeReference(continentEnumType, isNullable: false));
            landPlant.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(false));
            model.AddElement(landPlant);

            var tree = new EdmComplexType("NS", "Tree", landPlant, false, true);

            tree.AddStructuralProperty("Price", EdmCoreModel.Instance.GetDecimal(false));
            model.AddElement(tree);

            var flower = new EdmComplexType("NS", "Flower", landPlant, false, true);

            flower.AddStructuralProperty("Height", EdmCoreModel.Instance.GetDouble(false));
            model.AddElement(flower);

            // address
            var address = new EdmComplexType("NS", "Address");

            address.AddStructuralProperty("Street", EdmCoreModel.Instance.GetString(true));
            address.AddStructuralProperty("City", EdmCoreModel.Instance.GetString(true));
            model.AddElement(address);

            var coreDescription = CoreVocabularyModel.DescriptionTerm;
            var annotation      = new EdmVocabularyAnnotation(address, coreDescription, new EdmStringConstant("Complex type 'Address' description."));

            model.AddVocabularyAnnotation(annotation);

            annotation = new EdmVocabularyAnnotation(tree, coreDescription, new EdmStringConstant("Complex type 'Tree' description."));
            model.AddVocabularyAnnotation(annotation);

            annotation = new EdmVocabularyAnnotation(zoo, coreDescription, new EdmStringConstant("Entity type 'Zoo' description."));
            model.AddVocabularyAnnotation(annotation);

            annotation = new EdmVocabularyAnnotation(human, coreDescription, new EdmStringConstant("Entity type 'Human' description."));
            model.AddVocabularyAnnotation(annotation);

            return(model);
        }
        public void CollectionValueTest()
        {
            EdmModel model       = new EdmModel();
            var      complexType = new EdmComplexType("TestModel", "ComplexType").Property("Name", EdmPrimitiveTypeKind.String, true);

            model.AddElement(complexType);
            var owningType = new EdmEntityType("TestModel", "OwningType");

            owningType.AddKeys(owningType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false)));
            owningType.AddStructuralProperty("PrimitiveCollection", EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetInt32(false)));
            model.AddElement(owningType);
            model.Fixup();

            var primitiveMultiValue = PayloadBuilder.PrimitiveMultiValue("Collection(Edm.Int32)").Item(42).Item(43);

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new[]
            {
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "null collection in request - should fail.",
                    PayloadEdmModel  = model,
                    PayloadElement   = PayloadBuilder.Property("PrimitiveCollection",
                                                               PayloadBuilder.PrimitiveMultiValue("Collection(Edm.Int32)"))
                                       .JsonRepresentation("{\"value\":null }")
                                       .ExpectedProperty(owningType, "PrimitiveCollection"),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullNamedValueForNonNullableType", "value", "Collection(Edm.Int32)")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "null collection in response - should fail.",
                    PayloadEdmModel  = model,
                    PayloadElement   = PayloadBuilder.Property("PrimitiveCollection",
                                                               PayloadBuilder.PrimitiveMultiValue("Collection(Edm.Int32)"))
                                       .JsonRepresentation(
                        "{" +
                        "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Collection(Edm.Int32)\"," +
                        "\"value\":null" +
                        "}")
                                       .ExpectedProperty(owningType, "PrimitiveCollection"),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullNamedValueForNonNullableType", "value", "Collection(Edm.Int32)")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Primitive value for collection - should fail.",
                    PayloadEdmModel  = model,
                    PayloadElement   = PayloadBuilder.Property("PrimitiveCollection",
                                                               PayloadBuilder.PrimitiveMultiValue("Collection(Edm.Int32)")
                                                               .JsonRepresentation("42"))
                                       .ExpectedProperty(owningType, "PrimitiveCollection"),
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "StartArray", "PrimitiveValue")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Object value for collection - should fail.",
                    PayloadEdmModel  = model,
                    PayloadElement   = PayloadBuilder.Property("PrimitiveCollection",
                                                               PayloadBuilder.PrimitiveMultiValue("Collection(Edm.Int32)")
                                                               .JsonRepresentation("{}"))
                                       .ExpectedProperty(owningType, "PrimitiveCollection"),
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetectedWithPropertyName", "StartArray", "StartObject", "value")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Simple primitive collection.",
                    PayloadEdmModel  = model,
                    PayloadElement   = PayloadBuilder.Property("PrimitiveCollection",
                                                               primitiveMultiValue
                                                               .JsonRepresentation("[42,43]")
                                                               .AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                                       .ExpectedProperty(owningType, "PrimitiveCollection"),
                    ExpectedResultPayloadElement = tc => tc.IsRequest
                        ? PayloadBuilder.Property(string.Empty, primitiveMultiValue)
                        : PayloadBuilder.Property("PrimitiveCollection", primitiveMultiValue)
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();
                testDescriptor.RunTest(testConfiguration);
            });
        }
예제 #31
0
        public void ComplexValueTest()
        {
            var injectedProperties = new[]
            {
                new
                {
                    InjectedJSON      = string.Empty,
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    InjectedJSON      = "\"@custom.annotation\": null",
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    InjectedJSON      = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataAnnotationNamespacePrefix + "unknown\": { }",
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    InjectedJSON      = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\": { }",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties", JsonLightConstants.ODataContextAnnotationName)
                },
                new
                {
                    InjectedJSON      = "\"@custom.annotation\": null, \"@custom.annotation\": 42",
                    ExpectedException = (ExpectedException)null
                },
            };

            var payloads = new[]
            {
                new
                {
                    Json          = "{0}",
                    ExpectedValue = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true)
                },
                new
                {
                    Json          = "{0}{1} \"Name\": \"Value\"",
                    ExpectedValue = PayloadBuilder.Entity("TestModel.ComplexType")
                                    .PrimitiveProperty("Name", "Value").IsComplex(true)
                },
                new
                {
                    Json          = "\"Name\": \"Value\"{1}{0}",
                    ExpectedValue = PayloadBuilder.Entity("TestModel.ComplexType")
                                    .PrimitiveProperty("Name", "Value").IsComplex(true)
                },
                new
                {
                    Json          = "\"Name\":\"Value\",{0}{1}\"City\":\"Redmond\"",
                    ExpectedValue = PayloadBuilder.Entity("TestModel.ComplexType")
                                    .PrimitiveProperty("Name", "Value")
                                    .PrimitiveProperty("City", "Redmond")
                                    .IsComplex(true)
                },
            };

            EdmModel model = new EdmModel();

            var addressType = new EdmComplexType("TestModel", "Address");

            addressType.AddStructuralProperty("Street", EdmCoreModel.Instance.GetString(isNullable: false));

            var complexType = new EdmComplexType("TestModel", "ComplexType");

            complexType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(isNullable: false));
            complexType.AddStructuralProperty("City", EdmCoreModel.Instance.GetString(isNullable: false));
            complexType.AddStructuralProperty("Address", new EdmComplexTypeReference(addressType, isNullable: false));
            complexType.AddStructuralProperty("Location", EdmPrimitiveTypeKind.GeographyPoint);

            var owningType = new EdmEntityType("TestModel", "OwningType");

            owningType.AddKeys(owningType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(isNullable: false)));
            owningType.AddStructuralProperty("TopLevelProperty", new EdmComplexTypeReference(complexType, isNullable: true));
            model.AddElement(owningType);
            model.AddElement(addressType);
            model.AddElement(complexType);

            var container = new EdmEntityContainer("TestModel", "DefaultContainer");

            container.AddEntitySet("OwningType", owningType);
            model.AddElement(container);

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = payloads.SelectMany(payload => injectedProperties.Select(injectedProperty =>
            {
                var json = string.Format(payload.Json, injectedProperty.InjectedJSON, string.IsNullOrEmpty(injectedProperty.InjectedJSON) ? string.Empty : ",");
                json     = string.Format("{{{0}{1}{2}}}",
                                         "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.ComplexType\"",
                                         string.IsNullOrEmpty(json) ? string.Empty : ",", json);
                return(new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadKind = ODataPayloadKind.Resource,
                    PayloadElement = payload.ExpectedValue.DeepCopy()
                                     .JsonRepresentation(json)
                                     // JSON Light payloads don't store complex type names since the type can be inferred from the context URI and or API.
                                     .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    })
                                     .ExpectedEntityType(complexType),
                    PayloadEdmModel = model,
                    ExpectedException = injectedProperty.ExpectedException,
                    ExpectedResultPayloadElement = tc => tc.IsRequest
                        ? payload.ExpectedValue
                                                   .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }).IsComplex(true)
                        : payload.ExpectedValue
                                                   .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }).IsComplex(true)
                });
            }));

            var explicitPayloadsForPrimitiveAndArray = new[]
            {
                new
                {
                    Description       = "Primitive value as complex - should fail.",
                    Json              = "42",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType"),
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "StartObject", "PrimitiveValue")
                },
                new
                {
                    Description       = "Array value as complex - should fail.",
                    Json              = "[]",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType"),
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "StartObject", "StartArray")
                },
            };

            testDescriptors = testDescriptors.Concat(explicitPayloadsForPrimitiveAndArray.Select(payload =>
            {
                return(new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = payload.ExpectedPayload.DeepCopy()
                                     .JsonRepresentation(payload.Json)
                                     // JSON Light payloads don't store complex type names since the type can be inferred from the context URI and or API.
                                     .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    })
                                     .ExpectedEntityType(complexType),
                    PayloadEdmModel = model,
                    ExpectedException = payload.ExpectedException,
                    DebugDescription = payload.Description,
                    ExpectedResultPayloadElement = tc => payload.ExpectedPayload.DeepCopy()
                                                   .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    })
                });
            }));

            var explicitPayloads = new[]
            {
                new
                {
                    Description = "Type annotation preceded by custom annotation - should fail",
                    Json        = "\"@custom.annotation\": null," +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"TestModel.ComplexType\"," +
                                  "\"Name\": \"Value\"",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_ResourceTypeAnnotationNotFirst")
                },
                new
                {
                    Description = "Custom property annotation - should be ignored.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", "custom.annotation") + "\": null," +
                                  "\"Name\": \"Value\"",
                    ExpectedPayload = PayloadBuilder.Entity("TestModel.ComplexType")
                                      .PrimitiveProperty("Name", "Value").IsComplex(true),
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    Description = "Duplicate custom property annotation - should not fail.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", "custom.annotation") + "\": null," +
                                  "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", "custom.annotation") + "\": 42," +
                                  "\"Name\": \"Value\"",
                    ExpectedPayload = PayloadBuilder.Entity("TestModel.ComplexType")
                                      .PrimitiveProperty("Name", "Value").IsComplex(true),
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    Description = "Unrecognized odata property annotation - should fail.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", JsonLightConstants.ODataAnnotationNamespacePrefix + "unknown") + "\": null," +
                                  "\"Name\": \"Value\"",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").PrimitiveProperty("Name", "Value").IsComplex(true),
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    Description = "Custom property annotation after the property - should fail.",
                    Json        = "\"Name\": \"Value\"," +
                                  "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", "custom.annotation") + "\": null",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("PropertyAnnotationAfterTheProperty", "custom.annotation", "Name")
                },
                new
                {
                    Description = "OData property annotation.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", JsonLightConstants.ODataTypeAnnotationName) + "\": \"Edm.String\"," +
                                  "\"Name\": \"Value\"",
                    ExpectedPayload = PayloadBuilder.Entity("TestModel.ComplexType")
                                      .PrimitiveProperty("Name", "Value").IsComplex(true),
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    Description = "Duplicate odata property annotation.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", JsonLightConstants.ODataTypeAnnotationName) + "\": \"Edm.Int32\"," +
                                  "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", JsonLightConstants.ODataTypeAnnotationName) + "\": \"Edm.String\"," +
                                  "\"Name\": \"Value\"",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicateAnnotationForPropertyNotAllowed", JsonLightConstants.ODataTypeAnnotationName, "Name")
                },
                new
                {
                    Description = "Property with object value and type name annotation - should fail.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Address", JsonLightConstants.ODataTypeAnnotationName) + "\":\"TestModel.Address\"," +
                                  "\"Address\":{}",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_ComplexValueWithPropertyTypeAnnotation", JsonLightConstants.ODataTypeAnnotationName)
                },
                new
                {
                    Description = "String property with type annotation after the property - should fail.",
                    Json        = "\"Name\":\"value\"," +
                                  "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", JsonLightConstants.ODataTypeAnnotationName) + "\":\"Edm.String\"",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("PropertyAnnotationAfterTheProperty", JsonLightConstants.ODataTypeAnnotationName, "Name")
                },
                new
                {
                    Description = "String property with null type annotation - should fail.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", JsonLightConstants.ODataTypeAnnotationName) + "\":null," +
                                  "\"Name\":\"value\"",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_InvalidTypeName", string.Empty)
                },
                new
                {
                    Description = "null property with unknown type annotation - should fail.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", JsonLightConstants.ODataTypeAnnotationName) + "\":\"Unknown\"," +
                                  "\"Name\":null",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "Unknown", "Primitive", "Complex"),
                },
                new
                {
                    Description       = "Spatial property with odata.type annotation inside the GeoJson object - should fail.",
                    Json              = "\"Location\":" + SpatialUtils.GetSpatialStringValue(ODataFormat.Json, GeographyFactory.Point(33.1, -110.0).Build(), "Edm.GeographyPoint"),
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_ODataTypeAnnotationInPrimitiveValue", JsonLightConstants.ODataTypeAnnotationName),
                },
                new
                {
                    Description = "Spatial property with odata.type annotation inside and outside the GeoJson object - should fail.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Location", JsonLightConstants.ODataTypeAnnotationName) + "\":\"Edm.GeographyPoint\"," +
                                  "\"Location\":" + SpatialUtils.GetSpatialStringValue(ODataFormat.Json, GeographyFactory.Point(33.1, -110.0).Build(), "Edm.GeographyPoint"),
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_ODataTypeAnnotationInPrimitiveValue", JsonLightConstants.ODataTypeAnnotationName),
                },
            };

            testDescriptors = testDescriptors.Concat(explicitPayloads.Select(payload =>
            {
                var json = string.Format("{{{0}{1}{2}}}",
                                         "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.ComplexType\"",
                                         string.IsNullOrEmpty(payload.Json) ? string.Empty : ",", payload.Json);
                return(new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = payload.ExpectedPayload.DeepCopy()
                                     .JsonRepresentation(json)
                                     // JSON Light payloads don't store complex type names since the type can be inferred from the context URI and or API.
                                     .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    })
                                     .ExpectedEntityType(complexType),
                    PayloadEdmModel = model,
                    ExpectedException = payload.ExpectedException,
                    DebugDescription = payload.Description,
                    ExpectedResultPayloadElement = tc => payload.ExpectedPayload.DeepCopy()
                                                   .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    })
                });
            }));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();
                testDescriptor.RunTest(testConfiguration);
            });
        }
            public Task<IEdmModel> GetModelAsync(ModelContext context, CancellationToken cancellationToken)
            {
                var model = new EdmModel();
                var entityType = new EdmEntityType(
                    "TestNamespace", "TestName");
                var entityContainer = new EdmEntityContainer(
                    "TestNamespace", "Entities");
                entityContainer.AddEntitySet("TestEntitySet", entityType);
                model.AddElement(entityType);
                model.AddElement(entityContainer);

                return Task.FromResult<IEdmModel>(model);
            }
예제 #33
0
        private static IEdmModel BuildModel()
        {
            EdmModel model = new EdmModel();

            var movieType = new EdmEntityType("TestModel", "Movie");
            EdmStructuralProperty idProperty = new EdmStructuralProperty(movieType, "Id", EdmCoreModel.Instance.GetInt32(false));

            movieType.AddProperty(idProperty);
            movieType.AddKeys(idProperty);
            movieType.AddProperty(new EdmStructuralProperty(movieType, "Name", EdmCoreModel.Instance.GetString(true)));
            model.AddElement(movieType);

            var tvMovieType = new EdmEntityType("TestModel", "TVMovie", movieType);

            tvMovieType.AddProperty(new EdmStructuralProperty(tvMovieType, "Channel", EdmCoreModel.Instance.GetString(false)));
            model.AddElement(tvMovieType);

            EdmEntityContainer defaultContainer = new EdmEntityContainer("TestModel", "Default");

            defaultContainer.AddEntitySet("Movies", movieType);
            model.AddElement(defaultContainer);

            EdmAction simpleAction = new EdmAction("TestModel", "SimpleAction", null /*returnType*/, false /*isBound*/, null /*entitySetPath*/);

            model.AddElement(simpleAction);
            defaultContainer.AddActionImport(simpleAction);

            EdmAction checkoutAction1 = new EdmAction("TestModel", "Checkout", EdmCoreModel.Instance.GetInt32(false), false /*isBound*/, null /*entitySetPath*/);

            checkoutAction1.AddParameter("movie", movieType.ToTypeReference());
            checkoutAction1.AddParameter("duration", EdmCoreModel.Instance.GetInt32(false));
            model.AddElement(checkoutAction1);

            EdmAction rateAction1 = new EdmAction("TestModel", "Rate", null /*returnType*/, true /*isBound*/, null /*entitySetPath*/);

            rateAction1.AddParameter("movie", movieType.ToTypeReference());
            rateAction1.AddParameter("rating", EdmCoreModel.Instance.GetInt32(false));
            model.AddElement(rateAction1);

            EdmAction changeChannelAction1 = new EdmAction("TestModel", "ChangeChannel", null /*returnType*/, true /*isBound*/, null /*entitySetPath*/);

            changeChannelAction1.AddParameter("movie", tvMovieType.ToTypeReference());
            changeChannelAction1.AddParameter("channel", EdmCoreModel.Instance.GetString(false));
            model.AddElement(changeChannelAction1);

            EdmAction checkoutAction = new EdmAction("TestModel", "Checkout", EdmCoreModel.Instance.GetInt32(false) /*returnType*/, false /*isBound*/, null /*entitySetPath*/);

            checkoutAction.AddParameter("movie", movieType.ToTypeReference());
            checkoutAction.AddParameter("duration", EdmCoreModel.Instance.GetInt32(false));
            model.AddElement(checkoutAction);

            var movieCollectionTypeReference = (new EdmCollectionType(movieType.ToTypeReference(nullable: false))).ToTypeReference(nullable: false);

            EdmAction checkoutMultiple1Action = new EdmAction("TestModel", "CheckoutMultiple", EdmCoreModel.Instance.GetInt32(false), false /*isBound*/, null /*entitySetPath*/);

            checkoutMultiple1Action.AddParameter("movies", movieCollectionTypeReference);
            checkoutMultiple1Action.AddParameter("duration", EdmCoreModel.Instance.GetInt32(false));
            model.AddElement(checkoutMultiple1Action);

            EdmAction rateMultiple1Action = new EdmAction("TestModel", "RateMultiple", null /*returnType*/, true /*isBound*/, null /*entitySetPath*/);

            rateMultiple1Action.AddParameter("movies", movieCollectionTypeReference);
            rateMultiple1Action.AddParameter("rating", EdmCoreModel.Instance.GetInt32(false));
            model.AddElement(rateMultiple1Action);

            EdmAction checkoutMultiple2Action = new EdmAction("TestModel", "CheckoutMultiple", EdmCoreModel.Instance.GetInt32(false) /*returnType*/, false /*isBound*/, null /*entitySetPath*/);

            checkoutMultiple2Action.AddParameter("movies", movieCollectionTypeReference);
            checkoutMultiple2Action.AddParameter("duration", EdmCoreModel.Instance.GetInt32(false));
            model.AddElement(checkoutMultiple2Action);

            EdmAction rateMultiple2Action = new EdmAction("TestModel", "RateMultiple", null /*returnType*/, true /*isBound*/, null /*entitySetPath*/);

            rateMultiple2Action.AddParameter("movies", movieCollectionTypeReference);
            rateMultiple2Action.AddParameter("rating", EdmCoreModel.Instance.GetInt32(false));
            model.AddElement(rateMultiple2Action);

            return(model);
        }