Exemple #1
0
        public void ParseTypeCastOnNavigationPropertyWithDerivedTypeConstraintAnnotationWorks(bool isInLine)
        {
            string annotation =
                @"<Annotation Term=""Org.OData.Validation.V1.DerivedTypeConstraint"" >" +
                "<Collection>" +
                "<String>NS.VipCustomer</String>" +
                "</Collection>" +
                "</Annotation>";

            IEdmModel edmModel = GetNavigationPropertyEdmModel(annotation, isInLine);

            IEdmEntityType customer               = edmModel.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "Customer");
            IEdmEntityType vipCustomer            = edmModel.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "VipCustomer");
            IEdmType       collectionCustomerType = new EdmCollectionType(new EdmEntityTypeReference(customer, true));

            int index = 1;

            foreach (string segment in new[] { "DirectReport", "SubCustomers" })
            {
                IEdmType actualType = index == 1 ? customer : collectionCustomerType;

                // verify the positive type cast on itself
                ODataPathParser pathParser = new ODataPathParser(new ODataUriParserConfiguration(edmModel));
                var             path       = pathParser.ParsePath(new[] { "Customers(1)", segment, "NS.Customer" });
                path[3].ShouldBeTypeSegment(actualType, customer);

                // verify the positive type cast
                path = pathParser.ParsePath(new[] { "Customers(1)", segment, "NS.VipCustomer" });
                path[3].ShouldBeTypeSegment(actualType, vipCustomer);

                // verify the negative type cast
                Action parsePath = () => pathParser.ParsePath(new[] { "Customers(1)", segment, "NS.NormalCustomer" });
                parsePath.ShouldThrow <ODataException>().WithMessage(ErrorStrings.PathParser_TypeCastOnlyAllowedInDerivedTypeConstraint("NS.NormalCustomer", "navigation property", segment));
                index++;
            }
        }
Exemple #2
0
        public void SelectAction_WithCast_Returns_ExpectedActionName(string method, string expected)
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();

            IEdmCollectionType collection = new EdmCollectionType(new EdmEntityTypeReference(model.SpecialCustomer, isNullable: false));

            ODataPath odataPath = new ODataPath(new EntitySetSegment(model.Customers),
                                                new TypeSegment(collection, model.Customers));

            var controllerContext = new HttpControllerContext()
            {
                Request   = new HttpRequestMessage(new HttpMethod(method), "http://localhost/"),
                RouteData = new HttpRouteData(new HttpRoute())
            };

            ILookup <string, HttpActionDescriptor> actionMap = new HttpActionDescriptor[1].ToLookup(desc => expected);

            // Act
            string actionName = new EntitySetRoutingConvention().SelectAction(odataPath, controllerContext, actionMap);

            // Assert
            Assert.Equal(expected, actionName);
        }
Exemple #3
0
        public void ParseTypeCastOnPropertyWithDerivedTypeConstraintAnnotationWorks(bool isInLine)
        {
            string annotation =
                @"<Annotation Term=""Org.OData.Validation.V1.DerivedTypeConstraint"" >" +
                "<Collection>" +
                "<String>NS.UsAddress</String>" +
                "</Collection>" +
                "</Annotation>";

            IEdmModel edmModel = GetPropertyEdmModel(annotation, isInLine);

            IEdmComplexType address               = edmModel.SchemaElements.OfType <IEdmComplexType>().First(c => c.Name == "Address");
            IEdmComplexType usAddress             = edmModel.SchemaElements.OfType <IEdmComplexType>().First(c => c.Name == "UsAddress");
            IEdmType        collectionAddressType = new EdmCollectionType(new EdmComplexTypeReference(address, true));

            int index = 1;

            foreach (string segment in new[] { "Address", "Locations" })
            {
                IEdmType actualType = index == 1 ? address : collectionAddressType;

                // verify the positive type cast on itself
                ODataPathParser pathParser = new ODataPathParser(new ODataUriParserConfiguration(edmModel));
                var             path       = pathParser.ParsePath(new[] { "Customers(1)", segment, "NS.Address" });
                path[3].ShouldBeTypeSegment(actualType, address);

                // verify the positive type cast
                path = pathParser.ParsePath(new[] { "Customers(1)", segment, "NS.UsAddress" });
                path[3].ShouldBeTypeSegment(actualType, usAddress);

                // verify the negative type cast
                Action parsePath = () => pathParser.ParsePath(new[] { "Customers(1)", segment, "NS.CnAddress" });
                parsePath.ShouldThrow <ODataException>().WithMessage(ErrorStrings.PathParser_TypeCastOnlyAllowedInDerivedTypeConstraint("NS.CnAddress", "property", segment));
                index++;
            }
        }
        public void ParseTypeCastOnNavigationPropertyWithoutDerivedTypeConstraintAnnotationWorks(string propertyName, string key, string typeCast)
        {
            IEdmModel edmModel = GetNavigationPropertyEdmModel("");

            ODataPathParser pathParser = new ODataPathParser(new ODataUriParserConfiguration(edmModel));

            IEdmEntityType         customer = edmModel.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "Customer");
            IEdmNavigationProperty property = customer.NavigationProperties().First(c => c.Name == propertyName);
            IEdmType collectionCustomerType = new EdmCollectionType(new EdmEntityTypeReference(customer, true));

            IEdmType castType = edmModel.FindDeclaredType(typeCast);

            Assert.NotNull(castType);

            int      index        = key != null ? 4 : 3;
            IEdmType actualType   = propertyName == "SubCustomers" && key == null ? collectionCustomerType : customer;
            IEdmType expectedType = propertyName == "SubCustomers" && key == null ?
                                    new EdmCollectionType(new EdmEntityTypeReference(castType as IEdmEntityType, true)) : castType;

            // ~/Customers(1)/{propertyName}/{typeCast}
            var path = pathParser.ParsePath(new[] { "Customers(1)", propertyName + key, typeCast });

            path[index].ShouldBeTypeSegment(expectedType, actualType);
        }
        public UriParameterReaderIntegrationTests()
        {
            model = new EdmModel();

            cityT = new EdmComplexType(ns, "City");
            cityT.AddStructuralProperty("CityName", EdmPrimitiveTypeKind.String, false);
            cityT.AddStructuralProperty("AreaCode", EdmPrimitiveTypeKind.String, true);
            model.AddElement(cityT);

            addressT = new EdmComplexType(ns, "Address");
            addressT.AddStructuralProperty("City", new EdmComplexTypeReference(cityT, true));
            model.AddElement(addressT);

            companyAddressT = new EdmComplexType(ns, "CompanyAddress", addressT, false);
            companyAddressT.AddStructuralProperty("CompanyName", EdmPrimitiveTypeKind.String);
            model.AddElement(companyAddressT);

            otherInfoT = new EdmComplexType(ns, "OtherInfo", null, false, true);
            otherInfoT.AddStructuralProperty("Hight", EdmPrimitiveTypeKind.Int32);
            model.AddElement(otherInfoT);

            personT = new EdmEntityType("NS", "Person", null, false, true);
            var Id = personT.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false));

            personT.AddKeys(Id);
            personT.AddStructuralProperty("Address", new EdmComplexTypeReference(addressT, false));
            personT.AddStructuralProperty("CompanyAddress", new EdmComplexTypeReference(companyAddressT, true));
            billingAddressesT = new EdmCollectionType(new EdmComplexTypeReference(addressT, false));
            personT.AddStructuralProperty("BillingAddresses", new EdmCollectionTypeReference(billingAddressesT));
            model.AddElement(personT);

            EdmEntityContainer container = new EdmEntityContainer(ns, "Container");

            peopleSet = new EdmEntitySet(container, "people", personT);
            model.AddElement(container);
        }
Exemple #6
0
        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("CountryOrRegion", 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("Microsoft.AspNet.OData.Test.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 IEdmModel GetEdmModelWithOperations(out IEdmEntityType customerType, out IEdmEntitySet customers)
        {
            EdmModel      model    = new EdmModel();
            EdmEntityType customer = new EdmEntityType("NS", "Customer");

            customerType = customer;
            customer.AddKeys(customer.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            model.AddElement(customer);

            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);

            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 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 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 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", "ModelWithInheritance");

            model.AddElement(container);
            customers = container.AddEntitySet("Customers", customer);

            return(model);
        }
Exemple #8
0
        private static IEdmTypeReference GetEdmTypeReference(Dictionary <Type, IEdmType> availableTypes, IEdmTypeConfiguration configuration, bool nullable)
        {
            Contract.Assert(availableTypes != null);

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

            EdmTypeKind kind = configuration.Kind;

            if (kind == EdmTypeKind.Collection)
            {
                CollectionTypeConfiguration collectionType    = (CollectionTypeConfiguration)configuration;
                EdmCollectionType           edmCollectionType =
                    new EdmCollectionType(GetEdmTypeReference(availableTypes, collectionType.ElementType, nullable));
                return(new EdmCollectionTypeReference(edmCollectionType));
            }
            else
            {
                Type configurationClrType = TypeHelper.GetUnderlyingTypeOrSelf(configuration.ClrType);

                if (!TypeHelper.IsEnum(configurationClrType))
                {
                    configurationClrType = configuration.ClrType;
                }

                IEdmType type;

                if (availableTypes.TryGetValue(configurationClrType, out type))
                {
                    if (kind == EdmTypeKind.Complex)
                    {
                        return(new EdmComplexTypeReference((IEdmComplexType)type, nullable));
                    }
                    else if (kind == EdmTypeKind.Entity)
                    {
                        return(new EdmEntityTypeReference((IEdmEntityType)type, nullable));
                    }
                    else if (kind == EdmTypeKind.Enum)
                    {
                        return(new EdmEnumTypeReference((IEdmEnumType)type, nullable));
                    }
                    else
                    {
                        throw Error.InvalidOperation(SRResources.UnsupportedEdmTypeKind, kind.ToString());
                    }
                }
                else if (configuration.Kind == EdmTypeKind.Primitive)
                {
                    PrimitiveTypeConfiguration primitiveTypeConfiguration = (PrimitiveTypeConfiguration)configuration;
                    EdmPrimitiveTypeKind       typeKind = EdmTypeBuilder.GetTypeKind(primitiveTypeConfiguration.ClrType);
                    return(EdmCoreModel.Instance.GetPrimitive(typeKind, nullable));
                }
                else if (configuration.Kind == EdmTypeKind.Untyped)
                {
                    return(EdmCoreModel.Instance.GetUntyped());
                }
                else
                {
                    throw Error.InvalidOperation(SRResources.NoMatchingIEdmTypeFound, configuration.FullName);
                }
            }
        }
Exemple #9
0
        /// <summary>
        /// This method is called by method call like Where/OfType/SelectMany and so on
        /// to create a model reference for whole function call.
        /// </summary>
        /// <param name="methodCall">
        /// An method call expression node.
        /// </param>
        /// <param name="source">
        /// The parameter model reference.
        /// </param>
        /// <param name="model">
        /// The edm model.
        /// </param>
        /// <returns>
        /// A reference to the model element
        /// that represents the expression node.
        /// </returns>
        private static QueryModelReference ComputeQueryModelReference(
            MethodCallExpression methodCall, QueryModelReference source, IEdmModel model)
        {
            var method = methodCall.Method;

            // source is a sequence of T and output is also a sequence of T
            var sourceType = method.GetParameters()[0].ParameterType.FindGenericType(typeof(IEnumerable <>));
            var resultType = method.ReturnType.FindGenericType(typeof(IEnumerable <>));

            if (sourceType == resultType)
            {
                return(new QueryModelReference(source.EntitySet, source.Type));
            }

            Type resultElementType = null;

            if (resultType != null)
            {
                resultElementType = resultType.GenericTypeArguments[0];
            }

            // In case sourceType IEnumerable<Person> and resultType is
            // IEnumerable <SelectExpandBinder.SelectAllAndExpand<Person>>
            // or IEnumerable<SelectExpandBinder.SelectAll<Person>>
            // or IEnumerable<SelectExpandBinder.SelectSome<Person>>
            // or IEnumerable<SelectExpandBinder.SelectSomeAndInheritance<Person>>
            if (sourceType != null && resultType != null)
            {
                var resultGenericType = resultElementType;
                if (resultGenericType.IsGenericType)
                {
                    var resultFinalElementType = resultGenericType.GenericTypeArguments[0];
                    var sourceElementType      = sourceType.GenericTypeArguments[0];

                    // Handle source is type of sub class and result is a base class
                    if (resultFinalElementType.IsAssignableFrom(sourceElementType))
                    {
                        return(new QueryModelReference(source.EntitySet, source.Type));
                    }
                }
            }

            // In this case, the sourceType is null
            if (method.Name.Equals(MethodNameOfType))
            {
                // Did not consider multiple namespaces have same entity type case or customized namespace
                var edmEntityType  = model.FindDeclaredType(resultElementType.FullName);
                var collectionType = new EdmCollectionType(
                    new EdmEntityTypeReference((IEdmEntityType)edmEntityType, false));
                return(new QueryModelReference(source.EntitySet, collectionType));
            }

            // Till here, it means the result is not part of previous result and entity set will be null
            // This mean result is a collection as resultType is IEnumerable<>
            if (resultType != null)
            {
                // Did not consider multiple namespaces have same entity type case or customized namespace
                var edmElementType = model.FindDeclaredType(resultElementType.FullName);

                // This means result is collection of Entity/Complex/Enum
                IEdmTypeReference edmTypeReference = null;
                if (edmElementType != null)
                {
                    var edmType = edmElementType as IEdmType;
                    edmTypeReference = edmType.GetTypeReference();

                    if (edmTypeReference != null)
                    {
                        var collectionType = new EdmCollectionType(edmTypeReference);
                        return(new QueryModelReference(null, collectionType));
                    }
                }

                // TODO Here means a collection of primitive type
            }

            // TODO Need to handle single result case
            // TODO GitHubIssue#29 : Handle projection operators in query expression
            return(null);
        }
Exemple #10
0
        /// <summary>
        /// Try to bind namespace-qualified type cast segment.
        /// </summary>
        internal static bool TryBindTypeCastSegment(string identifier, string parenthesisExpressions, IEdmModel model,
                                                    IList <PathSegment> path,
                                                    PathParserSettings settings)
        {
            if (identifier == null || identifier.IndexOf('.') < 0)
            {
                // type cast should be namespace-qualified name
                return(false);
            }

            PathSegment preSegment = path.LastOrDefault();

            if (preSegment == null)
            {
                // type cast should not be the first segment.
                return(false);
            }

            IEdmSchemaType schemaType = model.ResolveType(identifier, settings.EnableCaseInsensitive);

            if (schemaType == null)
            {
                return(false);
            }

            IEdmType targetEdmType = schemaType as IEdmType;

            if (targetEdmType == null)
            {
                return(false);
            }

            IEdmType previousEdmType = preSegment.EdmType;
            bool     isNullable      = false;

            if (previousEdmType.TypeKind == EdmTypeKind.Collection)
            {
                previousEdmType = ((IEdmCollectionType)previousEdmType).ElementType.Definition;
                isNullable      = ((IEdmCollectionType)previousEdmType).ElementType.IsNullable;
            }

            if (!targetEdmType.IsOrInheritsFrom(previousEdmType) && !previousEdmType.IsOrInheritsFrom(targetEdmType))
            {
                throw new Exception($"Type cast {targetEdmType.FullTypeName()} has no relationship with previous {previousEdmType.FullTypeName()}.");
            }

            // We want the type of the type segment to be a collection if the previous segment was a collection
            IEdmType actualTypeOfTheTypeSegment = targetEdmType;

            if (preSegment.EdmType.TypeKind == EdmTypeKind.Collection)
            {
                var actualEntityTypeOfTheTypeSegment = targetEdmType as IEdmEntityType;
                if (actualEntityTypeOfTheTypeSegment != null)
                {
                    actualTypeOfTheTypeSegment = new EdmCollectionType(new EdmEntityTypeReference(actualEntityTypeOfTheTypeSegment, isNullable));
                }
                else
                {
                    // Complex collection supports type cast too.
                    var actualComplexTypeOfTheTypeSegment = actualTypeOfTheTypeSegment as IEdmComplexType;
                    if (actualComplexTypeOfTheTypeSegment != null)
                    {
                        actualTypeOfTheTypeSegment = new EdmCollectionType(new EdmComplexTypeReference(actualComplexTypeOfTheTypeSegment, isNullable));
                    }
                    else
                    {
                        throw new Exception($"Invalid type cast of {identifier}, it should be entity or complex.");
                    }
                }
            }

            TypeSegment typeCast = new TypeSegment(actualTypeOfTheTypeSegment, preSegment.EdmType, preSegment.NavigationSource, identifier);

            path.Add(typeCast);

            TryBindKeySegment(parenthesisExpressions, path);

            return(true);
        }
Exemple #11
0
        private static EdmCollectionTypeReference CreateCultureValuesCollectionTypeReference(IEdmComplexTypeReference cultureValueTypeReference)
        {
            var collectionType = new EdmCollectionType(cultureValueTypeReference);

            return(new EdmCollectionTypeReference(collectionType));
        }
        public void WriteUntypedValueTest()
        {
            EdmModel edmModel = new EdmModel();

            var jsonType    = new EdmComplexType("TestModel", "JsonType");
            var jsonTypeRef = new EdmComplexTypeReference(jsonType, isNullable: true);

            edmModel.AddElement(jsonType);

            var collectionType    = new EdmCollectionType(jsonTypeRef);
            var collectionTypeRef = new EdmCollectionTypeReference(collectionType);

            var entityType = new EdmEntityType("TestModel", "EntityType");

            entityType.AddStructuralProperty("Value", jsonTypeRef);
            entityType.AddStructuralProperty("CollectionValue", collectionTypeRef);
            edmModel.AddElement(entityType);

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

            container.AddEntitySet("EntitySet", entityType);
            edmModel.AddElement(container);

            const string JsonFormat = "$(NL){{{0},\"Value\":{1}}}";

            IEnumerable <PropertyPayloadTestCase> testCases = new[]
            {
                new PropertyPayloadTestCase
                {
                    DebugDescription = "Null.",
                    Property         = new ODataProperty
                    {
                        Name  = "Value",
                        Value = new ODataUntypedValue()
                        {
                            RawValue = "null"
                        }
                    },
                },
                new PropertyPayloadTestCase
                {
                    DebugDescription = "Integer.",
                    Property         = new ODataProperty
                    {
                        Name  = "Value",
                        Value = new ODataUntypedValue()
                        {
                            RawValue = "42"
                        }
                    },
                },
                new PropertyPayloadTestCase
                {
                    DebugDescription = "Float.",
                    Property         = new ODataProperty
                    {
                        Name  = "Value",
                        Value = new ODataUntypedValue()
                        {
                            RawValue = "3.1415"
                        }
                    },
                },
                new PropertyPayloadTestCase
                {
                    DebugDescription = "String.",
                    Property         = new ODataProperty
                    {
                        Name  = "Value",
                        Value = new ODataUntypedValue()
                        {
                            RawValue = "\"string\""
                        }
                    },
                },
                new PropertyPayloadTestCase
                {
                    DebugDescription = "Array of elements of mixed types.",
                    Property         = new ODataProperty
                    {
                        Name  = "Value",
                        Value = new ODataUntypedValue()
                        {
                            RawValue = "[1, 2, \"abc\"]"
                        }
                    },
                },
                new PropertyPayloadTestCase
                {
                    DebugDescription = "Array of arrays.",
                    Property         = new ODataProperty
                    {
                        Name  = "Value",
                        Value = new ODataUntypedValue()
                        {
                            RawValue = "[ [1, \"abc\"], [2, \"def\"], [[3],[4, 5]] ]"
                        }
                    },
                },
                new PropertyPayloadTestCase
                {
                    DebugDescription = "Negative - empty RawValue",
                    Property         = new ODataProperty
                    {
                        Name  = "Value",
                        Value = new ODataUntypedValue()
                        {
                            RawValue = string.Empty
                        },
                    },
                    ExpectedException = ODataExpectedExceptions.ODataException(
                        TextRes.ODataJsonLightValueSerializer_MissingRawValueOnUntyped),
                },
                new PropertyPayloadTestCase
                {
                    DebugDescription = "Collection of Edm.Untyped elements.",
                    Property         = new ODataProperty
                    {
                        Name  = "CollectionValue",
                        Value = new ODataCollectionValue()
                        {
                            TypeName = "Collection(TestModel.JsonType)",
                            Items    = new object[]
                            {
                                new ODataUntypedValue()
                                {
                                    RawValue = "\"string\""
                                },
                                new ODataUntypedValue()
                                {
                                    RawValue = "[1, 2, \"abc\"]"
                                },
                                new ODataUntypedValue()
                                {
                                    RawValue = "3.1415"
                                }
                            }
                        }
                    },
                },
                new PropertyPayloadTestCase
                {
                    DebugDescription = "Integer.",
                    Property         = new ODataProperty
                    {
                        Name  = "Value",
                        Value = new ODataPrimitiveValue(42)
                    },
                },
                new PropertyPayloadTestCase
                {
                    DebugDescription = "Float.",
                    Property         = new ODataProperty
                    {
                        Name  = "Value",
                        Value = new ODataPrimitiveValue(3.1415)
                    },
                },
                new PropertyPayloadTestCase
                {
                    DebugDescription = "String.",
                    Property         = new ODataProperty
                    {
                        Name  = "Value",
                        Value = new ODataPrimitiveValue("string")
                    },
                },
            };

            IEnumerable <PayloadWriterTestDescriptor <ODataProperty> > testDescriptors = testCases.Select(testCase =>
                                                                                                          new PayloadWriterTestDescriptor <ODataProperty>(
                                                                                                              this.Settings,
                                                                                                              testCase.Property,
                                                                                                              tc => new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
            {
                Json = string.Format(
                    CultureInfo.InvariantCulture,
                    JsonFormat,
                    JsonLightWriterUtils.GetMetadataUrlPropertyForEntry("EntitySet"),
                    GetExpectedJson(testCase.Property.Value)),
                FragmentExtractor  = (result) => result.RemoveAllAnnotations(false),
                ExpectedException2 = testCase.ExpectedException,
            })
            {
                DebugDescription = testCase.DebugDescription,
                Model            = edmModel,
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.WriterTestConfigurationProvider.JsonLightFormatConfigurationsWithIndent,
                (testDescriptor, testConfiguration) =>
            {
                TestWriterUtils.WriteAndVerifyTopLevelContent(
                    testDescriptor,
                    testConfiguration,
                    (messageWriter) =>
                {
                    messageWriter.PrivateSettings.Validations = ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;
                    messageWriter.WriteProperty(testDescriptor.PayloadItems.Single());
                },
                    this.Assert,
                    baselineLogger: this.Logger);
            });
        }
        private void WriteTopLevelComplexCollectionProperty(bool inherit)
        {
            EdmModel       model       = new EdmModel();
            EdmComplexType complexType = AddAndGetComplexType(model);

            if (inherit)
            {
                EdmComplexType derivedComplexType = new EdmComplexType("Fake", "DerivedComplexType", complexType);
                derivedComplexType.AddStructuralProperty("D1", EdmPrimitiveTypeKind.String);
                model.AddElement(derivedComplexType);
            }

            EdmEntityType entityType = AddAndGetEntityType(model);
            var           collectionOfComplexType = new EdmCollectionType(new EdmComplexTypeReference(complexType, true));

            entityType.AddStructuralProperty("CollectionOfComplexP",
                                             new EdmCollectionTypeReference(collectionOfComplexType));
            var entitySet = GetEntitySet(model, entityType);

            var requestUri = new Uri("http://temp.org/FakeSet('parent')/CollectionOfComplexP");
            var odataUri   = new ODataUri {
                RequestUri = requestUri
            };

            odataUri.Path = new ODataUriParser(model, new Uri("http://temp.org/"), requestUri).ParsePath();

            ODataResourceSet collectionP = new ODataResourceSet();
            ODataResource    complexP    = new ODataResource()
            {
                Properties = new[] { new ODataProperty {
                                         Name = "P1", Value = "complexValue"
                                     }, }
            };

            Action <ODataWriter> write = (writer) =>
            {
                writer.WriteStart(collectionP);
                writer.WriteStart(complexP);
                writer.WriteEnd();
                writer.WriteEnd();
            };

            var expected = "{" +
                           "\"@odata.context\":\"http://temp.org/$metadata#FakeSet('parent')/CollectionOfComplexP\"," +
                           "\"value\":" +
                           "[" +
                           "{" +
                           "\"P1\":\"complexValue\"" +
                           "}" +
                           "]" +
                           "}";

            if (inherit)
            {
                ODataResource dComplexP = new ODataResource()
                {
                    TypeName   = "Fake.DerivedComplexType",
                    Properties = new[]
                    {
                        new ODataProperty {
                            Name = "P1", Value = "complexValue"
                        },
                        new ODataProperty {
                            Name = "D1", Value = "derivedComplexValue"
                        }
                    }
                };

                write = (writer) =>
                {
                    writer.WriteStart(collectionP);
                    writer.WriteStart(complexP);
                    writer.WriteEnd();
                    writer.WriteStart(dComplexP);
                    writer.WriteEnd();
                    writer.WriteEnd();
                };

                expected = "{" +
                           "\"@odata.context\":\"http://temp.org/$metadata#FakeSet('parent')/CollectionOfComplexP\"," +
                           "\"value\":" +
                           "[" +
                           "{" +
                           "\"P1\":\"complexValue\"" +
                           "}," +
                           "{" +
                           "\"@odata.type\":\"#Fake.DerivedComplexType\"," +
                           "\"P1\":\"complexValue\"," +
                           "\"D1\":\"derivedComplexValue\"" +
                           "}" +
                           "]" +
                           "}";
            }

            var actual = WriteJsonLightEntry(
                isRequest: false,
                serviceDocumentUri: new Uri("http://temp.org/"),
                specifySet: false,
                odataEntry: null,
                entitySet: null,
                resourceType: complexType,
                odataUri: odataUri,
                writeAction: write,
                isResourceSet: true,
                model: model);

            actual.Should().Be(expected);
        }
Exemple #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        public virtual bool AppliesToAction(ODataControllerActionContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            ActionModel action = context.Action;

            if (context.EntitySet == null && context.Singleton == null)
            {
                return(false);
            }
            IEdmNavigationSource navigationSource = context.EntitySet == null ?
                                                    (IEdmNavigationSource)context.Singleton :
                                                    (IEdmNavigationSource)context.EntitySet;

            IEdmModel      model           = context.Model;
            string         prefix          = context.Prefix;
            IEdmEntityType entityType      = navigationSource.EntityType();
            bool           hasKeyParameter = HasKeyParameter(entityType, action);

            // found
            int      keyNumber = entityType.Key().Count();
            IEdmType bindType  = entityType;

            if (!hasKeyParameter)
            {
                // bond to collection
                bindType  = new EdmCollectionType(new EdmEntityTypeReference(entityType, true));
                keyNumber = 0;
            }

            string actionName = action.ActionMethod.Name;
            var    operations = model.FindBoundOperations(bindType).Where(p => p.Name == actionName);

            var actions = operations.OfType <IEdmAction>().ToList();

            if (actions.Count == 1) // action overload on binding type, only one action overload on the same binding type
            {
                if (action.Parameters.Any(p => p.ParameterType == typeof(ODataActionParameters)))
                {
                    // we find a action route
                    IList <ODataSegmentTemplate> segments = new List <ODataSegmentTemplate>();

                    if (context.EntitySet != null)
                    {
                        segments.Add(new EntitySetSegmentTemplate(context.EntitySet));
                    }
                    else
                    {
                        segments.Add(new SingletonSegmentTemplate(context.Singleton));
                    }


                    if (hasKeyParameter)
                    {
                        segments.Add(new KeySegmentTemplate(entityType));
                    }
                    segments.Add(new ActionSegmentTemplate(actions[0], false));

                    ODataPathTemplate template = new ODataPathTemplate(segments);

                    action.AddSelector(prefix, model, template);
                    return(true);
                }
            }

            var          functions = operations.OfType <IEdmFunction>().ToList();
            IEdmFunction function  = FindMatchFunction(keyNumber, functions, action);

            if (function != null)
            {
                IList <ODataSegmentTemplate> segments = new List <ODataSegmentTemplate>();

                if (context.EntitySet != null)
                {
                    segments.Add(new EntitySetSegmentTemplate(context.EntitySet));
                }
                else
                {
                    segments.Add(new SingletonSegmentTemplate(context.Singleton));
                }

                if (hasKeyParameter)
                {
                    segments.Add(new KeySegmentTemplate(entityType));
                }
                segments.Add(new FunctionSegmentTemplate(function, false));

                ODataPathTemplate template = new ODataPathTemplate(segments);

                action.AddSelector(prefix, model, template);
                return(true);
            }

            // in OData operationImport routing convention, all action are processed by default
            // even it's not a really edm operation import call.
            return(false);
        }
        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);
        }
        /// <summary>
        /// Convert to collection type reference from element type reference
        /// </summary>
        /// <param name="elementTypeReference">The element type reference</param>
        /// <returns>The colleciton type reference</returns>
        public static IEdmCollectionTypeReference ToCollectionTypeReference(this IEdmTypeReference elementTypeReference)
        {
            var collectionDefinition = new EdmCollectionType(elementTypeReference);

            return(collectionDefinition.ToTypeReference());
        }
        /// <summary>
        /// This method is called by method call like Where/OfType/SelectMany and so on
        /// to create a model reference for whole function call.
        /// </summary>
        /// <param name="methodCall">
        /// An method call expression node.
        /// </param>
        /// <param name="source">
        /// The parameter model reference.
        /// </param>
        /// <param name="model">
        /// The edm model.
        /// </param>
        /// <returns>
        /// A reference to the model element
        /// that represents the expression node.
        /// </returns>
        private static QueryModelReference ComputeQueryModelReference(
            MethodCallExpression methodCall, QueryModelReference source, IEdmModel model)
        {
            var method = methodCall.Method;

            // source is a sequence of T and output is also a sequence of T
            var sourceType = method.GetParameters()[0].ParameterType.FindGenericType(typeof(IEnumerable<>));
            var resultType = method.ReturnType.FindGenericType(typeof(IEnumerable<>));
            if (sourceType == resultType)
            {
                return new QueryModelReference(source.EntitySet, source.Type);
            }

            Type resultElementType = null;
            if (resultType != null)
            {
                resultElementType = resultType.GenericTypeArguments[0];
            }

            // In case sourceType IEnumerable<Person> and resultType is
            // IEnumerable <SelectExpandBinder.SelectAllAndExpand<Person>>
            // or IEnumerable<SelectExpandBinder.SelectAll<Person>>
            // or IEnumerable<SelectExpandBinder.SelectSome<Person>>
            // or IEnumerable<SelectExpandBinder.SelectSomeAndInheritance<Person>>
            if (sourceType != null && resultType != null)
            {
                var resultGenericType = resultElementType;
                if (resultGenericType.IsGenericType)
                {
                    var resultFinalElementType = resultGenericType.GenericTypeArguments[0];
                    var sourceElementType = sourceType.GenericTypeArguments[0];

                    // Handle source is type of sub class and result is a base class
                    if (resultFinalElementType.IsAssignableFrom(sourceElementType))
                    {
                        return new QueryModelReference(source.EntitySet, source.Type);
                    }
                }
            }

            // In this case, the sourceType is null
            if (method.Name.Equals(MethodNameOfType))
            {
                // Did not consider multiple namespaces have same entity type case or customized namespace
                var edmEntityType = model.FindDeclaredType(resultElementType.FullName);
                var collectionType = new EdmCollectionType(
                    new EdmEntityTypeReference((IEdmEntityType)edmEntityType, false));
                return new QueryModelReference(source.EntitySet, collectionType);
            }

            // Till here, it means the result is not part of previous result and entity set will be null
            // This mean result is a collection as resultType is IEnumerable<>
            if (resultType != null)
            {
                // Did not consider multiple namespaces have same entity type case or customized namespace
                var edmElementType = model.FindDeclaredType(resultElementType.FullName);

                // This means result is collection of Entity/Complex/Enum
                IEdmTypeReference edmTypeReference = null;
                if (edmElementType != null)
                {
                    var edmType = edmElementType as IEdmType;
                    edmTypeReference = edmType.GetTypeReference();

                    if (edmTypeReference != null)
                    {
                        var collectionType = new EdmCollectionType(edmTypeReference);
                        return new QueryModelReference(null, collectionType);
                    }
                }

                // TODO Here means a collection of primitive type
            }

            // TODO Need to handle single result case
            // TODO GitHubIssue#29 : Handle projection operators in query expression
            return null;
        }
        public void CollectionValueTest()
        {
            EdmModel       edmModel = new EdmModel();
            EdmComplexType edmComplexTypeMyComplexType = edmModel.ComplexType("MyComplexType", ModelNamespace);

            edmComplexTypeMyComplexType.Property("P1", EdmPrimitiveTypeKind.Int32, false).Property("P2", EdmPrimitiveTypeKind.String, true);
            edmModel.Fixup();

            var edmCollectionTypeOfIntegerType   = new EdmCollectionType(EdmCoreModel.Instance.GetInt32(false));
            var edmCollectionTypeOfMyComplexType = new EdmCollectionType(new EdmComplexTypeReference(edmComplexTypeMyComplexType, true));
            // Create payloads of the collection properties
            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new[]
            {
                // Empty element collection
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.Int32"))
                                     .XmlValueRepresentation(new XNode[0])
                                     .WithTypeAnnotation(edmCollectionTypeOfIntegerType),
                    PayloadEdmModel = edmModel,
                },
                // Collections containing collections are not supported
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue()
                                     .XmlValueRepresentation("<m:element />", EntityModelUtils.GetCollectionTypeName(EntityModelUtils.GetCollectionTypeName("Edm.String")), null)
                                     .WithTypeAnnotation(edmCollectionTypeOfIntegerType),
                    PayloadEdmModel   = edmModel,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_NestedCollectionsAreNotSupported"),
                },
            };

            var primitivePayloadsWithPadding = new CollectionPaddingPayloadTextCase <PrimitiveMultiValue>[]
            {
                new CollectionPaddingPayloadTextCase <PrimitiveMultiValue>
                {
                    XmlValue       = "{0}",
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.Int32"))
                                     .WithTypeAnnotation(edmCollectionTypeOfIntegerType)
                },
                new CollectionPaddingPayloadTextCase <PrimitiveMultiValue>
                {
                    XmlValue       = "{0}<m:element>42</m:element>",
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.Int32"))
                                     .Item(42)
                                     .WithTypeAnnotation(edmCollectionTypeOfIntegerType)
                },
                new CollectionPaddingPayloadTextCase <PrimitiveMultiValue>
                {
                    XmlValue       = "<m:element>42</m:element>{0}",
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.Int32"))
                                     .Item(42)
                                     .WithTypeAnnotation(edmCollectionTypeOfIntegerType)
                },
            };

            var complexPayloadsWithPadding = new CollectionPaddingPayloadTextCase <ComplexMultiValue>[]
            {
                new CollectionPaddingPayloadTextCase <ComplexMultiValue>
                {
                    XmlValue       = "<m:element><d:P1>42</d:P1></m:element>{0}<m:element><d:P2>test</d:P2></m:element>",
                    PayloadElement = PayloadBuilder.ComplexMultiValue(EntityModelUtils.GetCollectionTypeName("TestModel.MyComplexType"))
                                     .Item(PayloadBuilder.ComplexValue("TestModel.MyComplexType").PrimitiveProperty("P1", 42).AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                                     .Item(PayloadBuilder.ComplexValue("TestModel.MyComplexType").PrimitiveProperty("P2", "test").AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                                     .WithTypeAnnotation(edmCollectionTypeOfMyComplexType)
                },
            };

            var xmlPadding = new CollectionXmlPadding[]
            {
                // Nothing
                new CollectionXmlPadding
                {
                    Padding = string.Empty,
                },
                // Whitespace only
                new CollectionXmlPadding
                {
                    Padding = "  \r\n\t",
                },
                // Insignificant nodes
                new CollectionXmlPadding
                {
                    Padding = "<!--s--> <?value?>",
                },
                // Element in no namespace
                new CollectionXmlPadding
                {
                    Padding = "<foo xmlns=''/>",
                },
                // Element in custom namespace
                new CollectionXmlPadding
                {
                    Padding = "<c:foo xmlns:c='uri' attr='1'><c:child/>text</c:foo>",
                },
                // Element in metadata namespace (should be ignored as well)
                new CollectionXmlPadding
                {
                    Padding = "<m:properties/>",
                },
                // Element in atom namespace (should also be ignored)
                new CollectionXmlPadding
                {
                    Padding = "<entry/>",
                },
                // Significant nodes - will be ignored
                new CollectionXmlPadding
                {
                    Padding = "some text <![CDATA[cdata]]>",
                },
                // Element in the d namespace should fail
                new CollectionXmlPadding
                {
                    Padding           = "<d:foo/>",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomPropertyAndValueDeserializer_InvalidCollectionElement", "foo", "http://docs.oasis-open.org/odata/ns/metadata"),
                },
                // Element in the d namespace should fail (wrong name)
                new CollectionXmlPadding
                {
                    Padding           = "<d:Element/>",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomPropertyAndValueDeserializer_InvalidCollectionElement", "Element", "http://docs.oasis-open.org/odata/ns/metadata"),
                },
            };

            testDescriptors = testDescriptors.Concat(this.CreatePayloadWithPaddingTestDescriptor(
                                                         primitivePayloadsWithPadding, xmlPadding, edmModel));

            testDescriptors = testDescriptors.Concat(this.CreatePayloadWithPaddingTestDescriptor(
                                                         complexPayloadsWithPadding, xmlPadding, edmModel));

            testDescriptors = testDescriptors.Select(td => td.InProperty());

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration);
            });
        }
Exemple #19
0
        /// <summary>
        /// Creates a collection value type for the specified <paramref name="itemTypeReference"/>.
        /// </summary>
        /// <param name="itemTypeReference">The <see cref="IEdmPrimitiveTypeReference"/> for the item type.</param>
        /// <returns>The created <see cref="IEdmCollectionTypeReference"/>.</returns>
        public static IEdmCollectionTypeReference ToCollectionTypeReference(this IEdmPrimitiveTypeReference itemTypeReference)
        {
            IEdmCollectionType collectionType = new EdmCollectionType(itemTypeReference);

            return((IEdmCollectionTypeReference)ToTypeReference(collectionType));
        }
        public void CollectionWithHeterogenousItemsTest()
        {
            EdmModel       edmModel = new EdmModel();
            EdmComplexType edmComplexTypeMyComplexType = edmModel.ComplexType("MyComplexType", ModelNamespace);

            edmComplexTypeMyComplexType.Property("P1", EdmPrimitiveTypeKind.Int32, false).Property("P2", EdmPrimitiveTypeKind.String, true);
            edmModel.Fixup();

            var edmCollectionTypeOfIntegerType = new EdmCollectionType(EdmCoreModel.Instance.GetInt32(false));
            var edmCollectionTypeOfStringType  = new EdmCollectionType(EdmCoreModel.Instance.GetString(true));

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new[]
            {
                // Primitive collection with complex item
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.String"))
                                     .XmlValueRepresentation("<m:element><d:P1>0</d:P1><d:P2>Foo</d:P2></m:element>", EntityModelUtils.GetCollectionTypeName("Edm.String"), null)
                                     .WithTypeAnnotation(edmCollectionTypeOfStringType),
                    PayloadEdmModel   = edmModel,
                    ExpectedException = ODataExpectedExceptions.ODataException("XmlReaderExtension_InvalidNodeInStringValue", "Element"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.Int32"))
                                     .XmlValueRepresentation("<m:element>0</m:element><m:element><d:P1>0</d:P1><d:P2>Foo</d:P2></m:element>", EntityModelUtils.GetCollectionTypeName("Edm.Int32"), null)
                                     .WithTypeAnnotation(edmCollectionTypeOfIntegerType),
                    PayloadEdmModel   = edmModel,
                    ExpectedException = ODataExpectedExceptions.ODataException("XmlReaderExtension_InvalidNodeInStringValue", "Element"),
                },
                // Complex collection with primitive item
                // Note - the text nodes (of the primitive items) are ignored in complex values - leaving empty complex values
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue(EntityModelUtils.GetCollectionTypeName("TestModel.MyComplexType"))
                                     .Item(PayloadBuilder.ComplexValue("TestModel.MyComplexType").PrimitiveProperty("P1", 987).AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                                     .Item(PayloadBuilder.ComplexValue("TestModel.MyComplexType").PrimitiveProperty("P1", 123).AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                                     .XmlValueRepresentation("<m:element>Foo<d:P1>987</d:P1></m:element><m:element><d:P1>123</d:P1>Bar</m:element>", EntityModelUtils.GetCollectionTypeName("TestModel.MyComplexType"), null),
                    PayloadEdmModel = edmModel,
                },
                // Primitive collection containing a primitive and a nested collection
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.String"))
                                     .XmlValueRepresentation("<m:element>Foo</m:element><m:element><m:element>0</m:element><m:element>1</m:element></m:element>", EntityModelUtils.GetCollectionTypeName("Edm.String"), null)
                                     .WithTypeAnnotation(edmCollectionTypeOfStringType),
                    PayloadEdmModel   = edmModel,
                    ExpectedException = ODataExpectedExceptions.ODataException("XmlReaderExtension_InvalidNodeInStringValue", "Element"),
                },
            };

            testDescriptors = testDescriptors.Select(td => td.InProperty());

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration);
            });
        }
Exemple #21
0
        /// <summary>
        /// Creates a test model shared among parameter reader/writer tests.
        /// </summary>
        /// <returns>Returns a model with operation imports.</returns>
        public static IEdmModel BuildModelWithFunctionImport()
        {
            EdmCoreModel       coreModel            = EdmCoreModel.Instance;
            EdmModel           model                = new EdmModel();
            const string       defaultNamespaceName = DefaultNamespaceName;
            EdmEntityContainer container            = new EdmEntityContainer(defaultNamespaceName, "TestContainer");

            model.AddElement(container);

            EdmComplexType complexType = new EdmComplexType(defaultNamespaceName, "ComplexType");

            complexType.AddProperty(new EdmStructuralProperty(complexType, "PrimitiveProperty", coreModel.GetString(false)));
            complexType.AddProperty(new EdmStructuralProperty(complexType, "ComplexProperty", complexType.ToTypeReference(false)));
            model.AddElement(complexType);

            EdmEnumType enumType = new EdmEnumType(defaultNamespaceName, "EnumType");

            model.AddElement(enumType);

            EdmEntityType entityType = new EdmEntityType(defaultNamespaceName, "EntityType");

            entityType.AddKeys(new IEdmStructuralProperty[] { new EdmStructuralProperty(entityType, "ID", coreModel.GetInt32(false)) });
            entityType.AddProperty(new EdmStructuralProperty(entityType, "ComplexProperty", complexType.ToTypeReference()));

            container.AddFunctionAndFunctionImport(model, "FunctionImport_Primitive", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("primitive", coreModel.GetString(false));
            container.AddFunctionAndFunctionImport(model, "FunctionImport_NullablePrimitive", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("nullablePrimitive", coreModel.GetString(true));
            EdmCollectionType stringCollectionType = new EdmCollectionType(coreModel.GetString(true));

            container.AddFunctionAndFunctionImport(model, "FunctionImport_PrimitiveCollection", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("primitiveCollection", stringCollectionType.ToTypeReference(false));
            container.AddFunctionAndFunctionImport(model, "FunctionImport_Complex", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("complex", complexType.ToTypeReference(true));
            EdmCollectionType complexCollectionType = new EdmCollectionType(complexType.ToTypeReference());

            container.AddFunctionAndFunctionImport(model, "FunctionImport_ComplexCollection", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("complexCollection", complexCollectionType.ToTypeReference());
            container.AddFunctionAndFunctionImport(model, "FunctionImport_Entry", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, true /*bindable*/).Function.AsEdmFunction().AddParameter("entry", entityType.ToTypeReference());
            EdmCollectionType entityCollectionType = new EdmCollectionType(entityType.ToTypeReference());

            container.AddFunctionAndFunctionImport(model, "FunctionImport_Feed", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, true /*bindable*/).Function.AsEdmFunction().AddParameter("feed", entityCollectionType.ToTypeReference());
            container.AddFunctionAndFunctionImport(model, "FunctionImport_Stream", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("stream", coreModel.GetStream(false));
            container.AddFunctionAndFunctionImport(model, "FunctionImport_Enum", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("enum", enumType.ToTypeReference());

            var functionImport_PrimitiveTwoParameters = container.AddFunctionAndFunctionImport(model, "FunctionImport_PrimitiveTwoParameters", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/);
            var function_PrimitiveTwoParameters       = functionImport_PrimitiveTwoParameters.Function.AsEdmFunction();

            function_PrimitiveTwoParameters.AddParameter("p1", coreModel.GetInt32(false));
            function_PrimitiveTwoParameters.AddParameter("p2", coreModel.GetString(false));

            container.AddFunctionAndFunctionImport(model, "FunctionImport_Int", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("p1", coreModel.GetInt32(false));
            container.AddFunctionAndFunctionImport(model, "FunctionImport_Double", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("p1", coreModel.GetDouble(false));
            EdmCollectionType int32CollectionType = new EdmCollectionType(coreModel.GetInt32(false));

            container.AddActionAndActionImport(model, "FunctionImport_NonNullablePrimitiveCollection", null /*returnType*/, null /*entitySet*/, false /*bindable*/).Action.AsEdmAction().AddParameter("p1", int32CollectionType.ToTypeReference(false));

            EdmComplexType complexType2 = new EdmComplexType(defaultNamespaceName, "ComplexTypeWithNullableProperties");

            complexType2.AddProperty(new EdmStructuralProperty(complexType2, "StringProperty", coreModel.GetString(true)));
            complexType2.AddProperty(new EdmStructuralProperty(complexType2, "IntegerProperty", coreModel.GetInt32(true)));
            model.AddElement(complexType2);

            EdmEnumType enumType1 = new EdmEnumType(defaultNamespaceName, "enumType1");

            enumType1.AddMember(new EdmEnumMember(enumType1, "enumType1_value1", new EdmEnumMemberValue(6)));
            model.AddElement(enumType1);

            var functionImport_MultipleNullableParameters = container.AddFunctionAndFunctionImport(model, "FunctionImport_MultipleNullableParameters", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/);
            var function_MultipleNullableParameters       = functionImport_MultipleNullableParameters.Function.AsEdmFunction();

            function_MultipleNullableParameters.AddParameter("p1", coreModel.GetBinary(true /*isNullable*/));
            function_MultipleNullableParameters.AddParameter("p2", coreModel.GetBoolean(true /*isNullable*/));
            function_MultipleNullableParameters.AddParameter("p3", coreModel.GetByte(true /*isNullable*/));
            function_MultipleNullableParameters.AddParameter("p5", coreModel.GetDateTimeOffset(true /*isNullable*/));
            function_MultipleNullableParameters.AddParameter("p6", coreModel.GetDecimal(true /*isNullable*/));
            function_MultipleNullableParameters.AddParameter("p7", coreModel.GetDouble(true /*isNullable*/));
            function_MultipleNullableParameters.AddParameter("p8", coreModel.GetGuid(true /*isNullable*/));
            function_MultipleNullableParameters.AddParameter("p9", coreModel.GetInt16(true /*isNullable*/));
            function_MultipleNullableParameters.AddParameter("p10", coreModel.GetInt32(true /*isNullable*/));
            function_MultipleNullableParameters.AddParameter("p11", coreModel.GetInt64(true /*isNullable*/));
            function_MultipleNullableParameters.AddParameter("p12", coreModel.GetSByte(true /*isNullable*/));
            function_MultipleNullableParameters.AddParameter("p13", coreModel.GetSingle(true /*isNullable*/));
            function_MultipleNullableParameters.AddParameter("p14", coreModel.GetSpatial(EdmPrimitiveTypeKind.GeographyPoint, true /*isNullable*/));
            function_MultipleNullableParameters.AddParameter("p15", coreModel.GetString(true /*isNullable*/));
            function_MultipleNullableParameters.AddParameter("p16", complexType2.ToTypeReference(true /*isNullable*/));
            function_MultipleNullableParameters.AddParameter("p17", enumType1.ToTypeReference(true /*isNullable*/));

            return(model);
        }
Exemple #22
0
        internal static IEdmCollectionTypeReference ToCollectionTypeReference(this IEdmPrimitiveTypeReference itemTypeReference)
        {
            IEdmCollectionType type = new EdmCollectionType(itemTypeReference);

            return((IEdmCollectionTypeReference)type.ToTypeReference());
        }
Exemple #23
0
        /// <summary>
        /// Gets the edm model. Constructs it if it doesn't exist
        /// </summary>
        /// <returns>Edm model</param>
        public IEdmModel GetModel()
        {
            if (this.model == null)
            {
                ConstructableMetadata metadata    = new ConstructableMetadata("InMemoryEntities", "Microsoft.Test.Taupo.OData.WCFService");
                IEdmComplexType       addressType = metadata.AddComplexType("Address", typeof(Address), null, false);
                metadata.AddPrimitiveProperty(addressType, "Street", typeof(string));
                metadata.AddPrimitiveProperty(addressType, "City", typeof(string));
                metadata.AddPrimitiveProperty(addressType, "PostalCode", typeof(string));

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

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

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

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

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

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

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

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

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

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

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

                // Function that returns a set of orders

                var collectionOrders = new EdmCollectionType(orderType.ToTypeReference()).ToTypeReference();
                metadata.AddFunction("OrdersWithMoreThanTwoItems", collectionOrders, collectionOrders, true, new EdmPathExpression("bindingparameter"), true /*iscomposable*/);

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

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

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

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

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

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

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

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

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

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

                // ACTIONS
                var action1 = metadata.AddAction("ChangeAddress", personType.ToTypeReference(), null /*returnType*/, true /*isbound*/, null /*entitySetPathExpression*/);
                action1.AddParameter(new EdmOperationParameter(action1, "Street", MetadataUtils.GetPrimitiveTypeReference(typeof(string))));
                action1.AddParameter(new EdmOperationParameter(action1, "City", MetadataUtils.GetPrimitiveTypeReference(typeof(string))));
                action1.AddParameter(new EdmOperationParameter(action1, "PostalCode", MetadataUtils.GetPrimitiveTypeReference(typeof(string))));

                metadata.AddActionImport("ChangeAddress", action1, null /*entitySet*/);

                // Unbound action with no parameters
                var getRecentCustomersAction = metadata.AddAction("GetRecentCustomers", null /*boundType*/, new EdmCollectionTypeReference(new EdmCollectionType(orderType.ToTypeReference())), false /*isbound*/, null /*entitySetPathExpression*/);
                metadata.AddActionImport("GetRecentCustomers", getRecentCustomersAction, orderset);

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

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

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

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

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

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

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

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

                this.model = metadata;
            }

            return(this.model);
        }
Exemple #24
0
        /// <summary>
        /// Combines the property types and returns a reference to the resulting facade.
        /// </summary>
        /// <param name="propertyName">The name of the navigation properties being combined. Used only for error messages.</param>
        /// <param name="clientProperty">The client property.</param>
        /// <param name="serverProperty">The server property.</param>
        /// <param name="modelFacade">The model facade.</param>
        /// <returns>
        /// A type reference to the combined type.
        /// </returns>
        private static IEdmTypeReference CombinePropertyTypes(string propertyName, IEdmNavigationProperty clientProperty, IEdmNavigationProperty serverProperty, EdmModelFacade modelFacade)
        {
            Debug.Assert(clientProperty != null, "clientProperty != null");
            Debug.Assert(serverProperty != null, "serverProperty != null");

            IEdmTypeReference clientPropertyType = clientProperty.Type;
            IEdmTypeReference serverPropertyType = serverProperty.Type;

            // ensure that either both sides are a collection or neither is.
            IEdmCollectionTypeReference clientCollectionType = clientPropertyType as IEdmCollectionTypeReference;
            IEdmCollectionTypeReference serverCollectionType = serverPropertyType as IEdmCollectionTypeReference;
            bool isCollection = clientCollectionType != null;

            if (isCollection != (serverCollectionType != null))
            {
                throw new InvalidOperationException(ErrorStrings.EdmNavigationPropertyFacade_InconsistentMultiplicity(propertyName));
            }

            // For collection properties: extract the element types, combine them, then recreate the collection.
            // For reference properties: get the entity types and combine them.
            IEdmType combinedType;

            if (isCollection)
            {
                // get the client element type and ensure it's an entity type.
                IEdmEntityTypeReference clientElementTypeReference = clientCollectionType.ElementType() as IEdmEntityTypeReference;
                if (clientElementTypeReference == null)
                {
                    throw new InvalidOperationException(ErrorStrings.EdmNavigationPropertyFacade_NonEntityType(propertyName, clientProperty.DeclaringType.FullName()));
                }

                // get the server element type and ensure it's an entity type.
                IEdmEntityTypeReference serverElementTypeReference = serverCollectionType.ElementType() as IEdmEntityTypeReference;
                if (serverElementTypeReference == null)
                {
                    throw new InvalidOperationException(ErrorStrings.EdmNavigationPropertyFacade_NonEntityType(propertyName, serverProperty.DeclaringType.FullName()));
                }

                // combine the element types.
                combinedType = modelFacade.CombineWithServerType(clientElementTypeReference.EntityDefinition(), serverElementTypeReference.EntityDefinition());

                // turn it back into a collection, maintaining nullability of the client's element type.
                combinedType = new EdmCollectionType(combinedType.ToEdmTypeReference(clientElementTypeReference.IsNullable));
            }
            else
            {
                // ensure the server property type is an entity type.
                IEdmEntityTypeReference clientEntityTypeReference = clientPropertyType as IEdmEntityTypeReference;
                if (clientEntityTypeReference == null)
                {
                    throw new InvalidOperationException(ErrorStrings.EdmNavigationPropertyFacade_NonEntityType(propertyName, clientProperty.DeclaringType.FullName()));
                }

                // ensure the server property type is an entity type.
                IEdmEntityTypeReference serverEntityTypeReference = serverPropertyType as IEdmEntityTypeReference;
                if (serverEntityTypeReference == null)
                {
                    throw new InvalidOperationException(ErrorStrings.EdmNavigationPropertyFacade_NonEntityType(propertyName, serverProperty.DeclaringType.FullName()));
                }

                combinedType = modelFacade.CombineWithServerType(clientEntityTypeReference.EntityDefinition(), serverEntityTypeReference.EntityDefinition());
            }

            // return a type reference, maintaining the original nullability from the client property type.
            return(combinedType.ToEdmTypeReference(clientPropertyType.IsNullable));
        }