示例#1
0
        public void CanCreateFunctionWithEntityReturnType()
        {
            // Arrange
            // Act
            ODataModelBuilder builder = new ODataModelBuilder();

            FunctionConfiguration createGoodCustomer = builder.Function("CreateGoodCustomer").ReturnsFromEntitySet <Customer>("GoodCustomers");
            FunctionConfiguration createBadCustomers = builder.Function("CreateBadCustomers").ReturnsCollectionFromEntitySet <Customer>("BadCustomers");

            // Assert
            EntityTypeConfiguration customer = createGoodCustomer.ReturnType as EntityTypeConfiguration;

            Assert.NotNull(customer);
            Assert.Equal(typeof(Customer).FullName, customer.FullName);
            EntitySetConfiguration goodCustomers = builder.EntitySets.SingleOrDefault(s => s.Name == "GoodCustomers");

            Assert.NotNull(goodCustomers);
            Assert.Same(createGoodCustomer.NavigationSource, goodCustomers);

            CollectionTypeConfiguration customers = createBadCustomers.ReturnType as CollectionTypeConfiguration;

            Assert.NotNull(customers);
            customer = customers.ElementType as EntityTypeConfiguration;
            Assert.NotNull(customer);
            EntitySetConfiguration badCustomers = builder.EntitySets.SingleOrDefault(s => s.Name == "BadCustomers");

            Assert.NotNull(badCustomers);
            Assert.Same(createBadCustomers.NavigationSource, badCustomers);
        }
示例#2
0
        public void CanCreateFunctionWithComplexReturnType()
        {
            // Arrange
            // Act
            ODataModelBuilder builder = new ODataModelBuilder();

            FunctionConfiguration createAddress   = builder.Function("CreateAddress").Returns <Address>();
            FunctionConfiguration createAddresses = builder.Function("CreateAddresses").ReturnsCollection <Address>();

            // Assert
            ComplexTypeConfiguration address = createAddress.ReturnType as ComplexTypeConfiguration;

            Assert.NotNull(address);
            Assert.Equal(typeof(Address).FullName, address.FullName);
            Assert.Null(createAddress.NavigationSource);

            CollectionTypeConfiguration addresses = createAddresses.ReturnType as CollectionTypeConfiguration;

            Assert.NotNull(addresses);
            Assert.Equal(string.Format("Collection({0})", typeof(Address).FullName), addresses.FullName);
            address = addresses.ElementType as ComplexTypeConfiguration;
            Assert.NotNull(address);
            Assert.Equal(typeof(Address).FullName, address.FullName);
            Assert.Null(createAddresses.NavigationSource);
        }
示例#3
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 = configuration as CollectionTypeConfiguration;
                bool elementNullable = EdmLibHelpers.IsNullable(collectionType.ElementType.ClrType);
                EdmCollectionType edmCollectionType =
                    new EdmCollectionType(GetEdmTypeReference(availableTypes, collectionType.ElementType, elementNullable));
                return(new EdmCollectionTypeReference(edmCollectionType));
            }
            else
            {
                Type configurationClrType = TypeHelper.GetUnderlyingTypeOrSelf(configuration.ClrType);

                if (!configurationClrType.IsEnum)
                {
                    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 = configuration as PrimitiveTypeConfiguration;
                    return(new EdmPrimitiveTypeReference(primitiveTypeConfiguration.EdmPrimitiveType, nullable));
                }
                else
                {
                    throw Error.InvalidOperation(SRResources.NoMatchingIEdmTypeFound, configuration.FullName);
                }
            }
        }
示例#4
0
        public ParameterConfiguration CollectionParameter <TElementType>(string name)
        {
            Type elementType = typeof(TElementType);
            IEdmTypeConfiguration       elementTypeConfiguration = GetProcedureTypeConfiguration(typeof(TElementType));
            CollectionTypeConfiguration parameterType            = new CollectionTypeConfiguration(elementTypeConfiguration, typeof(IEnumerable <>).MakeGenericType(elementType));

            return(AddParameter(name, parameterType));
        }
示例#5
0
        /// <summary>
        /// Sets the return type to a collection of EntityType instances.
        /// </summary>
        /// <typeparam name="TElementEntityType">The type that is an EntityType</typeparam>
        /// <param name="entitySetPath">The entitySetPath which contains the returned EntityType instances</param>
        internal void ReturnsCollectionViaEntitySetPathImplementation <TElementEntityType>(IEnumerable <string> entitySetPath) where TElementEntityType : class
        {
            Type clrCollectionType            = typeof(IEnumerable <TElementEntityType>);
            IEdmTypeConfiguration elementType = ModelBuilder.GetTypeConfigurationOrNull(typeof(TElementEntityType));

            ReturnType    = new CollectionTypeConfiguration(elementType, clrCollectionType);
            EntitySetPath = entitySetPath;
        }
示例#6
0
        internal void ReturnsCollectionFromEntitySetImplementation <TElementEntityType>(string entitySetName) where TElementEntityType : class
        {
            Type clrCollectionType = typeof(IEnumerable <TElementEntityType>);

            ModelBuilder.EntitySet <TElementEntityType>(entitySetName);
            NavigationSource = ModelBuilder.EntitySets.Single(s => s.Name == entitySetName);
            IEdmTypeConfiguration elementType = ModelBuilder.GetTypeConfigurationOrNull(typeof(TElementEntityType));

            ReturnType = new CollectionTypeConfiguration(elementType, clrCollectionType);
        }
示例#7
0
        public ParameterConfiguration CollectionEntityParameter <TElementEntityType>(string name) where TElementEntityType : class
        {
            Type elementType = typeof(TElementEntityType);
            IEdmTypeConfiguration elementTypeConfiguration =
                ModelBuilder.StructuralTypes.FirstOrDefault(t => t.ClrType == elementType) ??
                ModelBuilder.AddEntityType(elementType);

            CollectionTypeConfiguration parameterType = new CollectionTypeConfiguration(elementTypeConfiguration,
                                                                                        typeof(IEnumerable <>).MakeGenericType(elementType));

            return(AddParameter(name, parameterType));
        }
示例#8
0
        internal void ReturnsCollectionImplementation <TReturnElementType>()
        {
            // TODO: I don't like this temporary solution that says the CLR type of the collection is IEnumerable<T>.
            // It basically has no meaning. That said the CLR type is meaningful for IEdmTypeConfiguration
            // because I still think it is useful for IEdmPrimitiveTypes too.
            // You can imagine the override of this that takes a delegate using the correct CLR type for the return type.
            Type clrCollectionType = typeof(IEnumerable <TReturnElementType>);
            Type clrElementType    = typeof(TReturnElementType);
            IEdmTypeConfiguration edmElementType = GetProcedureTypeConfiguration(clrElementType);

            ReturnType = new CollectionTypeConfiguration(edmElementType, clrCollectionType);
        }
示例#9
0
        public ParameterConfiguration CollectionParameter <TElementType>(string name)
        {
            Type elementType = typeof(TElementType);

            if (elementType == typeof(DateTime) || elementType == typeof(DateTime?))
            {
                string typeName = typeof(IEnumerable <TElementType>).FullName;
                throw Error.InvalidOperation(SRResources.DateTimeTypeParametersNotSupported, typeName, name);
            }

            IEdmTypeConfiguration       elementTypeConfiguration = GetProcedureTypeConfiguration(elementType);
            CollectionTypeConfiguration parameterType            = new CollectionTypeConfiguration(elementTypeConfiguration, typeof(IEnumerable <>).MakeGenericType(elementType));

            return(AddParameter(name, parameterType));
        }
示例#10
0
        public ActionConfiguration ReturnsCollectionFromEntitySet <TElementEntityType>(
            EntitySetConfiguration <TElementEntityType> entitySetConfiguration) where TElementEntityType : class
        {
            if (entitySetConfiguration == null)
            {
                throw Error.ArgumentNull("entitySetConfiguration");
            }

            Type clrCollectionType = typeof(IEnumerable <TElementEntityType>);

            NavigationSource = entitySetConfiguration.EntitySet;
            IEdmTypeConfiguration elementType = ModelBuilder.GetTypeConfigurationOrNull(typeof(TElementEntityType));

            ReturnType = new CollectionTypeConfiguration(elementType, clrCollectionType);
            return(this);
        }
示例#11
0
        private static void AddProcedureLinkBuilder(IEdmModel model, IEdmOperation operation, ProcedureConfiguration procedure)
        {
            ActionConfiguration   actionConfiguration = procedure as ActionConfiguration;
            IEdmAction            action = operation as IEdmAction;
            FunctionConfiguration functionConfiguration = procedure as FunctionConfiguration;
            IEdmFunction          function = operation as IEdmFunction;

            if (procedure.BindingParameter.TypeConfiguration.Kind == EdmTypeKind.Entity)
            {
                if (actionConfiguration != null && actionConfiguration.GetActionLink() != null && action != null)
                {
                    model.SetActionLinkBuilder(
                        action,
                        new ActionLinkBuilder(actionConfiguration.GetActionLink(), actionConfiguration.FollowsConventions));
                }
                else if (functionConfiguration != null && functionConfiguration.GetFunctionLink() != null && function != null)
                {
                    model.SetFunctionLinkBuilder(
                        function,
                        new FunctionLinkBuilder(functionConfiguration.GetFunctionLink(), functionConfiguration.FollowsConventions));
                }
            }
            else if (procedure.BindingParameter.TypeConfiguration.Kind == EdmTypeKind.Collection)
            {
                CollectionTypeConfiguration collectionTypeConfiguration =
                    (CollectionTypeConfiguration)procedure.BindingParameter.TypeConfiguration;

                if (collectionTypeConfiguration.ElementType.Kind == EdmTypeKind.Entity)
                {
                    if (actionConfiguration != null && actionConfiguration.GetFeedActionLink() != null && action != null)
                    {
                        model.SetActionLinkBuilder(
                            action,
                            new ActionLinkBuilder(actionConfiguration.GetFeedActionLink(), actionConfiguration.FollowsConventions));
                    }
                    else if (functionConfiguration != null && functionConfiguration.GetFeedFunctionLink() != null && function != null)
                    {
                        model.SetFunctionLinkBuilder(
                            function,
                            new FunctionLinkBuilder(functionConfiguration.GetFeedFunctionLink(), functionConfiguration.FollowsConventions));
                    }
                }
            }
        }
        public void NonbindingParameterConfigurationSupportsParameterCollectionTypeAs(Type type, bool isNullable)
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            builder.EntityType<Customer>();
            builder.ComplexType<Address>();
            builder.EnumType<Color>();

            Type elementType;
            Assert.True(type.IsCollection(out elementType));

            // Act
            Type underlyingType = TypeHelper.GetUnderlyingTypeOrSelf(elementType);
            IEdmTypeConfiguration elementTypeConfiguration = builder.GetTypeConfigurationOrNull(underlyingType);
            CollectionTypeConfiguration collectionType = new CollectionTypeConfiguration(elementTypeConfiguration,
                typeof(IEnumerable<>).MakeGenericType(elementType));

            NonbindingParameterConfiguration parameter = new NonbindingParameterConfiguration("name", collectionType);

            // Assert
            Assert.Equal(isNullable, parameter.OptionalParameter);
        }
示例#13
0
        public void NonbindingParameterConfigurationSupportsParameterCollectionTypeAs(Type type, bool isNullable)
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();

            builder.EntityType <Customer>();
            builder.ComplexType <Address>();
            builder.EnumType <Color>();

            Type elementType;

            Assert.True(type.IsCollection(out elementType));

            // Act
            Type underlyingType = TypeHelper.GetUnderlyingTypeOrSelf(elementType);
            IEdmTypeConfiguration       elementTypeConfiguration = builder.GetTypeConfigurationOrNull(underlyingType);
            CollectionTypeConfiguration collectionType           = new CollectionTypeConfiguration(elementTypeConfiguration,
                                                                                                   typeof(IEnumerable <>).MakeGenericType(elementType));

            NonbindingParameterConfiguration parameter = new NonbindingParameterConfiguration("name", collectionType);

            // Assert
            Assert.Equal(isNullable, parameter.OptionalParameter);
        }
示例#14
0
        public void CanBuildOperationBoundToCollectionCacheForIEdmModel()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration <Customer> customer = builder.EntitySet <Customer>("Customers").EntityType;

            customer.HasKey(c => c.ID);
            customer.Property(c => c.Name);
            customer.ComplexProperty(c => c.Address);

            EntityTypeConfiguration <Movie> movie = builder.EntitySet <Movie>("Movies").EntityType;

            movie.HasKey(m => m.ID);
            movie.HasKey(m => m.Name);
            EntityTypeConfiguration <Blockbuster> blockBuster = builder.EntityType <Blockbuster>().DerivesFrom <Movie>();
            EntityTypeConfiguration movieConfiguration        = builder.StructuralTypes.OfType <EntityTypeConfiguration>().Single(t => t.Name == "Movie");

            // build actions that are bindable to the collection of entity
            customer.Collection.Action("CollectionCustomerActionInCache1");
            customer.Collection.Action("CollectionCustomerActionInCache2");
            movie.Collection.Action("CollectionMovieActionInCache3");

            ActionConfiguration         movieActionIncache4     = builder.Action("CollectionMovieActionInCache4");
            CollectionTypeConfiguration collectionConfiguration = new CollectionTypeConfiguration(movieConfiguration, typeof(Movie));

            movieActionIncache4.SetBindingParameter("bindingParameter", collectionConfiguration);

            blockBuster.Collection.Action("CollectionBlockbusterActionInCache5");

            // build functions that are bindable to the collection of entity
            customer.Collection.Function("CollectionCustomerFunctionInCache1").Returns <int>();
            customer.Collection.Function("CollectionCustomerFunctionInCache2").Returns <int>();
            movie.Collection.Function("CollectionMovieFunctionInCache3").Returns <int>();
            blockBuster.Collection.Function("CollectionBlockbusterFunctionInCache5").Returns <int>();

            // build actions that are either: bindable to an entity, have no parameter, have only complex parameter
            customer.Action("CustomersActionNotInCache1");
            customer.Function("CustomersFunctionNotInCache1").Returns <int>();
            movie.Action("MoviesActionNotInCache2");
            builder.Action("NoParametersNotInCache3");

            ActionConfiguration addressParameterNotInCache4 = builder.Action("AddressParameterNotInCache4");

            addressParameterNotInCache4.Parameter <Address>("address");

            IEdmModel model = builder.GetEdmModel();

            IEdmEntityType customerType    = model.SchemaElements.OfType <IEdmEntityType>().Single(e => e.Name == "Customer");
            IEdmEntityType movieType       = model.SchemaElements.OfType <IEdmEntityType>().Single(e => e.Name == "Movie");
            IEdmEntityType blockBusterType = model.SchemaElements.OfType <IEdmEntityType>().Single(e => e.Name == "Blockbuster");

            // Act
            BindableOperationFinder annotation = new BindableOperationFinder(model);
            var movieOperations       = annotation.FindOperationsBoundToCollection(movieType).ToArray();
            var customerOperations    = annotation.FindOperationsBoundToCollection(customerType).ToArray();
            var blockBusterOperations = annotation.FindOperationsBoundToCollection(blockBusterType).ToArray();

            // Assert
            Assert.Equal(3, movieOperations.Length);
            Assert.Single(movieOperations.Where(a => a.Name == "CollectionMovieActionInCache3"));
            Assert.Single(movieOperations.Where(a => a.Name == "CollectionMovieActionInCache4"));
            Assert.Single(movieOperations.Where(a => a.Name == "CollectionMovieFunctionInCache3"));

            Assert.Equal(4, customerOperations.Length);
            Assert.Single(customerOperations.Where(a => a.Name == "CollectionCustomerActionInCache1"));
            Assert.Single(customerOperations.Where(a => a.Name == "CollectionCustomerActionInCache2"));
            Assert.Single(customerOperations.Where(a => a.Name == "CollectionCustomerFunctionInCache1"));
            Assert.Single(customerOperations.Where(a => a.Name == "CollectionCustomerFunctionInCache2"));

            Assert.Equal(5, blockBusterOperations.Length);
            Assert.Single(blockBusterOperations.Where(a => a.Name == "CollectionBlockbusterActionInCache5"));
            Assert.Single(blockBusterOperations.Where(a => a.Name == "CollectionBlockbusterFunctionInCache5"));
            Assert.Single(blockBusterOperations.Where(a => a.Name == "CollectionMovieActionInCache3"));
            Assert.Single(blockBusterOperations.Where(a => a.Name == "CollectionMovieActionInCache4"));
            Assert.Single(blockBusterOperations.Where(a => a.Name == "CollectionMovieFunctionInCache3"));
        }
        public void CanBuildProcedureBoundToCollectionCacheForIEdmModel()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration<Customer> customer = builder.EntitySet<Customer>("Customers").EntityType;
            customer.HasKey(c => c.ID);
            customer.Property(c => c.Name);
            customer.ComplexProperty(c => c.Address);

            EntityTypeConfiguration<Movie> movie = builder.EntitySet<Movie>("Movies").EntityType;
            movie.HasKey(m => m.ID);
            movie.HasKey(m => m.Name);
            EntityTypeConfiguration<Blockbuster> blockBuster = builder.EntityType<Blockbuster>().DerivesFrom<Movie>();
            EntityTypeConfiguration movieConfiguration = builder.StructuralTypes.OfType<EntityTypeConfiguration>().Single(t => t.Name == "Movie");

            // build actions that are bindable to the collection of entity
            customer.Collection.Action("CollectionCustomerActionInCache1");
            customer.Collection.Action("CollectionCustomerActionInCache2");
            movie.Collection.Action("CollectionMovieActionInCache3");

            ActionConfiguration movieActionIncache4 = builder.Action("CollectionMovieActionInCache4");
            CollectionTypeConfiguration collectionConfiguration = new CollectionTypeConfiguration(movieConfiguration, typeof(Movie));
            movieActionIncache4.SetBindingParameter("bindingParameter", collectionConfiguration);

            blockBuster.Collection.Action("CollectionBlockbusterActionInCache5");

            // build functions that are bindable to the collection of entity
            customer.Collection.Function("CollectionCustomerFunctionInCache1").Returns<int>();
            customer.Collection.Function("CollectionCustomerFunctionInCache2").Returns<int>();
            movie.Collection.Function("CollectionMovieFunctionInCache3").Returns<int>();
            blockBuster.Collection.Function("CollectionBlockbusterFunctionInCache5").Returns<int>();

            // build actions that are either: bindable to an entity, have no parameter, have only complex parameter 
            customer.Action("CustomersActionNotInCache1");
            customer.Function("CustomersFunctionNotInCache1").Returns<int>();
            movie.Action("MoviesActionNotInCache2");
            builder.Action("NoParametersNotInCache3");

            ActionConfiguration addressParameterNotInCache4 = builder.Action("AddressParameterNotInCache4");
            addressParameterNotInCache4.Parameter<Address>("address");

            IEdmModel model = builder.GetEdmModel();

            IEdmEntityType customerType = model.SchemaElements.OfType<IEdmEntityType>().Single(e => e.Name == "Customer");
            IEdmEntityType movieType = model.SchemaElements.OfType<IEdmEntityType>().Single(e => e.Name == "Movie");
            IEdmEntityType blockBusterType = model.SchemaElements.OfType<IEdmEntityType>().Single(e => e.Name == "Blockbuster");

            // Act
            BindableProcedureFinder annotation = new BindableProcedureFinder(model);
            var movieOperations = annotation.FindProceduresBoundToCollection(movieType).ToArray();
            var customerOperations = annotation.FindProceduresBoundToCollection(customerType).ToArray();
            var blockBusterOperations = annotation.FindProceduresBoundToCollection(blockBusterType).ToArray();

            // Assert
            Assert.Equal(3, movieOperations.Length);
            Assert.Single(movieOperations.Where(a => a.Name == "CollectionMovieActionInCache3"));
            Assert.Single(movieOperations.Where(a => a.Name == "CollectionMovieActionInCache4"));
            Assert.Single(movieOperations.Where(a => a.Name == "CollectionMovieFunctionInCache3"));

            Assert.Equal(4, customerOperations.Length);
            Assert.Single(customerOperations.Where(a => a.Name == "CollectionCustomerActionInCache1"));
            Assert.Single(customerOperations.Where(a => a.Name == "CollectionCustomerActionInCache2"));
            Assert.Single(customerOperations.Where(a => a.Name == "CollectionCustomerFunctionInCache1"));
            Assert.Single(customerOperations.Where(a => a.Name == "CollectionCustomerFunctionInCache2"));
            
            Assert.Equal(5, blockBusterOperations.Length);
            Assert.Single(blockBusterOperations.Where(a => a.Name == "CollectionBlockbusterActionInCache5"));
            Assert.Single(blockBusterOperations.Where(a => a.Name == "CollectionBlockbusterFunctionInCache5"));
            Assert.Single(blockBusterOperations.Where(a => a.Name == "CollectionMovieActionInCache3"));
            Assert.Single(blockBusterOperations.Where(a => a.Name == "CollectionMovieActionInCache4"));
            Assert.Single(blockBusterOperations.Where(a => a.Name == "CollectionMovieFunctionInCache3"));
        }