예제 #1
0
        public void CanCreateEntityWithCollectionProperties()
        {
            var builder = new ODataModelBuilder();
            var customer = builder.Entity<Customer>();
            customer.HasKey(c => c.CustomerId);
            customer.CollectionProperty(c => c.Aliases);
            customer.CollectionProperty(c => c.Addresses);


            var aliasesProperty = customer.Properties.OfType<CollectionPropertyConfiguration>().SingleOrDefault(p => p.Name == "Aliases");
            var addressesProperty = customer.Properties.OfType<CollectionPropertyConfiguration>().SingleOrDefault(p => p.Name == "Addresses");

            Assert.Equal(3, customer.Properties.Count());
            Assert.Equal(2, customer.Properties.OfType<CollectionPropertyConfiguration>().Count());
            Assert.NotNull(aliasesProperty);
            Assert.Equal(typeof(string), aliasesProperty.ElementType);
            Assert.NotNull(addressesProperty);
            Assert.Equal(typeof(Address), addressesProperty.ElementType);

            Assert.Equal(2, builder.StructuralTypes.Count());
            var addressType = builder.StructuralTypes.Skip(1).FirstOrDefault();
            Assert.NotNull(addressType);
            Assert.Equal(EdmTypeKind.Complex, addressType.Kind);
            Assert.Equal(typeof(Address).FullName, addressType.FullName);

            var model = builder.GetServiceModel();
            var edmCustomerType = model.FindType(typeof(Customer).FullName) as IEdmEntityType;
            var edmAddressType = model.FindType(typeof(Address).FullName) as IEdmComplexType;
        }
        public void Apply_SingleForeignKeyOnForeignKeyProperty_Works()
        {
            // Arrange
            Type dependentType = typeof(SingleDependentEntity2);

            ODataModelBuilder builder = new ODataModelBuilder();
            builder.Entity<PrincipalEntity>().HasKey(p => p.PrincipalIntId);

            EntityTypeConfiguration dependentEntity = builder.AddEntity(dependentType);

            PropertyInfo expectPropertyInfo = dependentType.GetProperty("PrincipalId");
            PrimitivePropertyConfiguration primitiveProperty = dependentEntity.AddProperty(expectPropertyInfo);

            PropertyInfo propertyInfo = dependentType.GetProperty("Principal");
            NavigationPropertyConfiguration navigation = dependentEntity.AddNavigationProperty(propertyInfo,
                EdmMultiplicity.ZeroOrOne);
            navigation.AddedExplicitly = false;

            // Act
            new ForeignKeyAttributeConvention().Apply(primitiveProperty, dependentEntity);

            // Assert
            PropertyInfo actualPropertyInfo = Assert.Single(navigation.DependentProperties);
            Assert.Same(expectPropertyInfo, actualPropertyInfo);

            Assert.Equal("PrincipalIntId", Assert.Single(navigation.PrincipalProperties).Name);
            Assert.False(primitiveProperty.OptionalProperty);
        }
        public void CanBuildBoundProcedureCacheForIEdmModel()
        {
            // 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.Entity<Blockbuster>().DerivesFrom<Movie>();
            EntityTypeConfiguration movieConfiguration = builder.StructuralTypes.OfType<EntityTypeConfiguration>().Single(t => t.Name == "Movie");

            // build actions that are bindable to a single entity
            customer.Action("InCache1_CustomerAction");
            customer.Action("InCache2_CustomerAction");
            movie.Action("InCache3_MovieAction");
            ActionConfiguration incache4_MovieAction = builder.Action("InCache4_MovieAction");
            incache4_MovieAction.SetBindingParameter("bindingParameter", movieConfiguration, true);
            blockBuster.Action("InCache5_BlockbusterAction");

            // build actions that are either: bindable to a collection of entities, have no parameter, have only complex parameter 
            customer.Collection.Action("NotInCache1_CustomersAction");
            movie.Collection.Action("NotInCache2_MoviesAction");
            ActionConfiguration notInCache3_NoParameters = builder.Action("NotInCache3_NoParameters");
            ActionConfiguration notInCache4_AddressParameter = builder.Action("NotInCache4_AddressParameter");
            notInCache4_AddressParameter.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);
            IEdmAction[] movieActions = annotation.FindProcedures(movieType)
                .OfType<IEdmAction>()
                .ToArray();
            IEdmAction[] customerActions = annotation.FindProcedures(customerType)
                .OfType<IEdmAction>()
                .ToArray();
            IEdmAction[] blockBusterActions = annotation.FindProcedures(blockBusterType)
                .OfType<IEdmAction>()
                .ToArray();

            // Assert
            Assert.Equal(2, customerActions.Length);
            Assert.NotNull(customerActions.SingleOrDefault(a => a.Name == "InCache1_CustomerAction"));
            Assert.NotNull(customerActions.SingleOrDefault(a => a.Name == "InCache2_CustomerAction"));
            Assert.Equal(2, movieActions.Length);
            Assert.NotNull(movieActions.SingleOrDefault(a => a.Name == "InCache3_MovieAction"));
            Assert.NotNull(movieActions.SingleOrDefault(a => a.Name == "InCache4_MovieAction"));
            Assert.Equal(3, blockBusterActions.Length);
            Assert.NotNull(blockBusterActions.SingleOrDefault(a => a.Name == "InCache3_MovieAction"));
            Assert.NotNull(blockBusterActions.SingleOrDefault(a => a.Name == "InCache4_MovieAction"));
            Assert.NotNull(blockBusterActions.SingleOrDefault(a => a.Name == "InCache5_BlockbusterAction"));
        }
 public void CreateComplexTypeProperty()
 {
     var builder = new ODataModelBuilder().Add_Customer_EntityType().Add_Address_ComplexType();
     builder.Entity<Customer>().ComplexProperty(c => c.Address);
     var model = builder.GetServiceModel();
     var customerType = model.SchemaElements.OfType<IEdmEntityType>().Single();
     var addressProperty = customerType.FindProperty("Address");
     Assert.NotNull(addressProperty);
 }
 public UnboundFunctionPathSegmentTest()
 {
     ODataModelBuilder builder = new ODataModelBuilder();
     builder.Entity<MyCustomer>().HasKey(c => c.Id).Property(c => c.Name);
     builder.EntitySet<MyCustomer>("Customers");
     FunctionConfiguration function = builder.Function("TopCustomer");
     function.ReturnsFromEntitySet<MyCustomer>("Customers");
     builder.Function("MyFunction").Returns<string>();
     _model = builder.GetEdmModel();
     _container = _model.EntityContainers().Single();
 }
예제 #6
0
        // Adds a Customer EntityType that has no key properties
        public static ODataModelBuilder Add_Customer_No_Keys_EntityType(this ODataModelBuilder builder)
        {
            var customer = builder.Entity <Customer>();

            customer.Property(c => c.CustomerId);
            customer.Property(c => c.Name);
            customer.Property(c => c.Website);
            customer.Property(c => c.SharePrice);
            customer.Property(c => c.ShareSymbol);
            return(builder);
        }
예제 #7
0
        // Adds a Customer EntityType but allows caller to configure Keys()
        public static ODataModelBuilder Add_Customer_With_Keys_EntityType <TKey>(this ODataModelBuilder builder, Expression <Func <Customer, TKey> > keyDefinitionExpression)
        {
            var customer = builder.Entity <Customer>();

            customer.HasKey(keyDefinitionExpression);
            customer.Property(c => c.CustomerId);
            customer.Property(c => c.Name);
            customer.Property(c => c.Website);
            customer.Property(c => c.SharePrice);
            customer.Property(c => c.ShareSymbol);
            return(builder);
        }
예제 #8
0
        public static ODataModelBuilder Add_Order_EntityType(this ODataModelBuilder builder)
        {
            var order = builder.Entity <Order>();

            order.HasKey(o => o.OrderId);
            order.Property(o => o.OrderDate);
            order.Property(o => o.Price);
            order.Property(o => o.OrderDate);
            order.Property(o => o.DeliveryDate);
            order.Ignore(o => o.Cost);
            return(builder);
        }
예제 #9
0
        private static void RegisterCompanyEntity(ODataModelBuilder model)
        {
            var company = model.Entity <Company>();

            company.HasKey <int>(c => c.CompanyId);
            company.Property(c => c.Name);
            company.Property(c => c.Industry);
            company.Property(c => c.Founders);
            company.Property(c => c.FoundingDate);
            company.Property(c => c.Headquarters);
            company.Property(c => c.Revenue);
            company.Property(c => c.NumberOfEmployees);
        }
        public void NonbindingParameterConfigurationThrowsWhenParameterTypeIsEntity()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            builder.Entity<Customer>();

            // Act & Assert
            ArgumentException exception = Assert.Throws<ArgumentException>(() =>
            {
                NonbindingParameterConfiguration configuration = new NonbindingParameterConfiguration("name", builder.GetTypeConfigurationOrNull(typeof(Customer)));
            });
            Assert.True(exception.Message.Contains(string.Format("'{0}'", typeof(Customer).FullName)));
            Assert.Equal("parameterType", exception.ParamName);
        }
예제 #11
0
        public void GetIfMatchOrNoneMatch_ReturnsETag_SetETagHeaderValue(string header)
        {
            // Arrange
            HttpRequestMessage request      = new HttpRequestMessage();
            HttpConfiguration  cofiguration = new HttpConfiguration();

            request.SetConfiguration(cofiguration);
            Dictionary <string, object> properties = new Dictionary <string, object> {
                { "Name", "Foo" }
            };
            EntityTagHeaderValue etagHeaderValue = new DefaultODataETagHandler().CreateETag(properties);

            if (header.Equals("IfMatch"))
            {
                request.Headers.IfMatch.Add(etagHeaderValue);
            }
            else
            {
                request.Headers.IfNoneMatch.Add(etagHeaderValue);
            }

            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration <Customer> customer = builder.Entity <Customer>();

            customer.HasKey(c => c.Id);
            customer.Property(c => c.Id);
            customer.Property(c => c.Name).IsConcurrencyToken();
            IEdmModel model = builder.GetEdmModel();

            Mock <ODataPathSegment> mockSegment = new Mock <ODataPathSegment> {
                CallBase = true
            };

            mockSegment.Setup(s => s.GetEdmType(null)).Returns(model.GetEdmType(typeof(Customer)));
            mockSegment.Setup(s => s.GetEntitySet(null)).Returns((IEdmEntitySet)null);
            ODataPath odataPath = new ODataPath(new[] { mockSegment.Object });

            request.ODataProperties().Path = odataPath;
            ODataQueryContext context      = new ODataQueryContext(model, typeof(Customer));

            // Act
            ODataQueryOptions <Customer> query = new ODataQueryOptions <Customer>(context, request);
            ETag    result        = header.Equals("IfMatch") ? query.IfMatch : query.IfNoneMatch;
            dynamic dynamicResult = result;

            // Assert
            Assert.Equal("Foo", result["Name"]);
            Assert.Equal("Foo", dynamicResult.Name);
        }
예제 #12
0
        public void CreateStreamPrimitiveProperty()
        {
            ODataModelBuilder builder = new ODataModelBuilder();
            var file = builder.Entity<File>();
            var data = file.Property(f => f.StreamData);

            var model = builder.GetServiceModel();
            var fileType = model.SchemaElements.OfType<IEdmEntityType>().Single();
            var streamProperty = fileType.DeclaredProperties.SingleOrDefault(p => p.Name == "StreamData");

            Assert.Equal(PropertyKind.Primitive, data.Kind);

            Assert.NotNull(streamProperty);
            Assert.Equal("Edm.Stream", streamProperty.Type.FullName());
        }
        public static EntitySetConfiguration CreateOrReuseEntitySet <TElementEntityType>(ODataModelBuilder builder, string entitySetName) where TElementEntityType : class
        {
            EntitySetConfiguration entitySet = builder.EntitySets.SingleOrDefault(s => s.Name == entitySetName);

            if (entitySet == null)
            {
                builder.EntitySet <TElementEntityType>(entitySetName);
                entitySet = builder.EntitySets.Single(s => s.Name == entitySetName);
            }
            else
            {
                builder.Entity <TElementEntityType>();
            }
            return(entitySet);
        }
예제 #14
0
        public void CanCreateEntityWithCompoundKey()
        {
            var builder = new ODataModelBuilder();
            var customer = builder.Entity<Customer>();
            customer.HasKey(c => new { c.CustomerId, c.Name });
            customer.Property(c => c.SharePrice);
            customer.Property(c => c.ShareSymbol);
            customer.Property(c => c.Website);

            var model = builder.GetServiceModel();
            var customerType = model.FindType(typeof(Customer).FullName) as IEdmEntityType;
            Assert.Equal(5, customerType.Properties().Count());
            Assert.Equal(2, customerType.DeclaredKey.Count());
            Assert.NotNull(customerType.DeclaredKey.SingleOrDefault(k => k.Name == "CustomerId"));
            Assert.NotNull(customerType.DeclaredKey.SingleOrDefault(k => k.Name == "Name"));
        }
        public void GetEntry_UsesRouteModel_ForMultipleModels()
        {
            // Model 1 only has Name, Model 2 only has Age
            ODataModelBuilder builder1 = new ODataModelBuilder();
            var personType1            = builder1.Entity <FormatterPerson>().Property(p => p.Name);

            builder1.EntitySet <FormatterPerson>("People").HasIdLink(p => "link", false);
            var model1 = builder1.GetEdmModel();

            ODataModelBuilder builder2 = new ODataModelBuilder();

            builder2.Entity <FormatterPerson>().Property(p => p.Age);
            builder2.EntitySet <FormatterPerson>("People").HasIdLink(p => "link", false);
            var model2 = builder2.GetEdmModel();

            var config = new HttpConfiguration();

            config.Routes.MapODataRoute("OData1", "v1", model1);
            config.Routes.MapODataRoute("OData2", "v2", model2);

            using (HttpServer host = new HttpServer(config))
                using (HttpClient client = new HttpClient(host))
                {
                    using (HttpResponseMessage response = client.GetAsync("http://localhost/v1/People(10)").Result)
                    {
                        Assert.True(response.IsSuccessStatusCode);
                        JToken json = JToken.Parse(response.Content.ReadAsStringAsync().Result);

                        // Model 1 has the Name property but not the Age property
                        Assert.NotNull(json["Name"]);
                        Assert.Null(json["Age"]);
                    }

                    using (HttpResponseMessage response = client.GetAsync("http://localhost/v2/People(10)").Result)
                    {
                        Assert.True(response.IsSuccessStatusCode);
                        JToken json = JToken.Parse(response.Content.ReadAsStringAsync().Result);

                        // Model 2 has the Age property but not the Name property
                        Assert.Null(json["Name"]);
                        Assert.NotNull(json["Age"]);
                    }
                }
        }
        public void GetIfMatchOrNoneMatch_ReturnsETag_SetETagHeaderValue(string header)
        {
            // Arrange
            HttpRequestMessage request = new HttpRequestMessage();
            HttpConfiguration cofiguration = new HttpConfiguration();
            request.SetConfiguration(cofiguration);
            Dictionary<string, object> properties = new Dictionary<string, object> { { "Name", "Foo" } };
            EntityTagHeaderValue etagHeaderValue = new DefaultODataETagHandler().CreateETag(properties);
            if (header.Equals("IfMatch"))
            {
                request.Headers.IfMatch.Add(etagHeaderValue);
            }
            else
            {
                request.Headers.IfNoneMatch.Add(etagHeaderValue);
            }

            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration<Customer> customer = builder.Entity<Customer>();
            customer.HasKey(c => c.Id);
            customer.Property(c => c.Id);
            customer.Property(c => c.Name).IsConcurrencyToken();
            IEdmModel model = builder.GetEdmModel();

            Mock<ODataPathSegment> mockSegment = new Mock<ODataPathSegment> { CallBase = true };
            mockSegment.Setup(s => s.GetEdmType(null)).Returns(model.GetEdmType(typeof(Customer)));
            mockSegment.Setup(s => s.GetEntitySet(null)).Returns((IEdmEntitySet)null);
            ODataPath odataPath = new ODataPath(new[] { mockSegment.Object });
            request.SetODataPath(odataPath);
            ODataQueryContext context = new ODataQueryContext(model, typeof(Customer));

            // Act
            ODataQueryOptions<Customer> query = new ODataQueryOptions<Customer>(context, request);
            ETag result = header.Equals("IfMatch") ? query.IfMatch : query.IfNoneMatch;
            dynamic dynamicResult = result;

            // Assert
            Assert.Equal("Foo", result["Name"]);
            Assert.Equal("Foo", dynamicResult.Name);
        }
예제 #17
0
        public void Apply_MultiForeignKeysOnNavigationProperty_Works()
        {
            // Arrange
            Type dependentType = typeof(MultiDependentEntity);

            ODataModelBuilder builder = new ODataModelBuilder();

            builder.Entity <PrincipalEntity>().HasKey(p => new { p.PrincipalIntId, p.PrincipalStringId });

            EntityTypeConfiguration dependentEntity = builder.AddEntity(dependentType);

            PropertyInfo expectPropertyInfo1 = dependentType.GetProperty("PrincipalId1");

            dependentEntity.AddProperty(expectPropertyInfo1);

            PropertyInfo expectPropertyInfo2 = dependentType.GetProperty("PrincipalId2");

            dependentEntity.AddProperty(expectPropertyInfo2);

            PropertyInfo propertyInfo = typeof(MultiDependentEntity).GetProperty("Principal");
            NavigationPropertyConfiguration navigation = dependentEntity.AddNavigationProperty(propertyInfo,
                                                                                               EdmMultiplicity.One);

            navigation.AddedExplicitly = false;

            // Act
            new ForeignKeyAttributeConvention().Apply(navigation, dependentEntity);

            // Assert
            Assert.Equal(2, navigation.DependentProperties.Count());
            Assert.Same(expectPropertyInfo1, navigation.DependentProperties.First());
            Assert.Same(expectPropertyInfo2, navigation.DependentProperties.Last());

            Assert.Equal(2, navigation.PrincipalProperties.Count());
            Assert.Equal("PrincipalIntId", navigation.PrincipalProperties.First().Name);
            Assert.Equal("PrincipalStringId", navigation.PrincipalProperties.Last().Name);
        }
예제 #18
0
        public void CanCreateDerivedTypesInAnyOrder()
        {
            var builder = new ODataModelBuilder();

            builder
                .Entity<SportBike>()
                .DerivesFrom<Motorcycle>();

            builder
                .Entity<Car>()
                .DerivesFrom<Vehicle>();

            builder
                .Entity<Vehicle>();

            builder
                .Entity<Motorcycle>()
                .DerivesFrom<Vehicle>();

            IEdmModel model = builder.GetEdmModel();

            model.AssertHasEntityType(typeof(Vehicle));
            model.AssertHasEntityType(typeof(Car), typeof(Vehicle));
            model.AssertHasEntityType(typeof(Motorcycle), typeof(Vehicle));
            model.AssertHasEntityType(typeof(SportBike), typeof(Motorcycle));
        }
예제 #19
0
        public void DerivesFrom_Throws_WhenSettingTheBaseType_IfDuplicatePropertyInDerivedType()
        {
            var builder = new ODataModelBuilder();

            builder
                .Entity<Vehicle>()
                .Property(v => v.Model);

            builder
                .Entity<SportBike>()
                .DerivesFrom<Motorcycle>()
                .Property(c => c.Model);

            Assert.Throws<InvalidOperationException>(
                () => builder
                    .Entity<Motorcycle>()
                    .DerivesFrom<Vehicle>(),
                "Cannot define property 'Model' in the base entity type 'System.Web.Http.OData.Builder.TestModels.Motorcycle' as the derived type 'System.Web.Http.OData.Builder.TestModels.SportBike' already defines it.");
        }
예제 #20
0
        public void GetEntry_UsesRouteModel_ForMultipleModels()
        {
            // Model 1 only has Name, Model 2 only has Age
            ODataModelBuilder builder1 = new ODataModelBuilder();
            var personType1 = builder1.Entity<FormatterPerson>().Property(p => p.Name);
            builder1.EntitySet<FormatterPerson>("People").HasIdLink(p => "link", false);
            var model1 = builder1.GetEdmModel();

            ODataModelBuilder builder2 = new ODataModelBuilder();
            builder2.Entity<FormatterPerson>().Property(p => p.Age);
            builder2.EntitySet<FormatterPerson>("People").HasIdLink(p => "link", false);
            var model2 = builder2.GetEdmModel();

            var config = new HttpConfiguration();
            config.Routes.MapODataServiceRoute("OData1", "v1", model1);
            config.Routes.MapODataServiceRoute("OData2", "v2", model2);

            using (HttpServer host = new HttpServer(config))
            using (HttpClient client = new HttpClient(host))
            {
                using (HttpResponseMessage response = client.GetAsync("http://localhost/v1/People(10)").Result)
                {
                    Assert.True(response.IsSuccessStatusCode);
                    JToken json = JToken.Parse(response.Content.ReadAsStringAsync().Result);

                    // Model 1 has the Name property but not the Age property
                    Assert.NotNull(json["Name"]);
                    Assert.Null(json["Age"]);
                }

                using (HttpResponseMessage response = client.GetAsync("http://localhost/v2/People(10)").Result)
                {
                    Assert.True(response.IsSuccessStatusCode);
                    JToken json = JToken.Parse(response.Content.ReadAsStringAsync().Result);

                    // Model 2 has the Age property but not the Name property
                    Assert.Null(json["Name"]);
                    Assert.NotNull(json["Age"]);
                }
            }
        }
        public void ReturnsCollection_ThrowsInvalidOperationException_IfReturnTypeIsEntity()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            builder.Entity<Movie>();
            var action = builder.Action("action");

            // Act & Assert
            Assert.Throws<InvalidOperationException>(() => action.ReturnsCollection<Movie>(),
                "The EDM type 'System.Web.OData.Builder.Movie' is already declared as an entity type. Use the " +
                "method 'ReturnsCollectionFromEntitySet' if the return type is an entity collection.");
        }
        public void CanCreateEdmModel_WithBindableAction()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration<Customer> customer = builder.Entity<Customer>();
            customer.HasKey(c => c.CustomerId);
            customer.Property(c => c.Name);

            // Act
            ActionConfiguration sendEmail = customer.Action("ActionName");
            IEdmModel model = builder.GetEdmModel();

            // Assert
            IEdmAction action = Assert.Single(model.SchemaElements.OfType<IEdmAction>());
            Assert.True(action.IsBound);
            Assert.True(model.IsAlwaysBindable(action));
            Assert.Equal("ActionName", action.Name);
            Assert.Null(action.ReturnType);
            Assert.Equal(1, action.Parameters.Count());
            Assert.Equal(BindingParameterConfiguration.DefaultBindingParameterName, action.Parameters.Single().Name);
            Assert.Equal(typeof(Customer).FullName, action.Parameters.Single().Type.FullName());
        }
        public void CanCreateActionThatBindsToEntityCollection()
        {
            // Arrange
            // Act
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration<Customer> customer = builder.Entity<Customer>();
            ActionConfiguration sendEmail = customer.Collection.Action("SendEmail");

            // Assert
            Assert.True(sendEmail.IsBindable);
            Assert.True(sendEmail.IsAlwaysBindable);
            Assert.NotNull(sendEmail.Parameters);
            Assert.Equal(1, sendEmail.Parameters.Count());
            Assert.Equal(BindingParameterConfiguration.DefaultBindingParameterName, sendEmail.Parameters.Single().Name);
            Assert.Equal(string.Format("Collection({0})", typeof(Customer).FullName), sendEmail.Parameters.Single().TypeConfiguration.FullName);
        }
        public void CanCreateEdmModel_WithTransientBindableAction()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration<Customer> customer = builder.Entity<Customer>();
            customer.HasKey(c => c.CustomerId);
            customer.Property(c => c.Name);
            // Act
            ActionConfiguration sendEmail = customer.TransientAction("ActionName");
            IEdmModel model = builder.GetEdmModel();

            // Assert
            IEdmEntityContainer container = model.EntityContainers().SingleOrDefault();
            Assert.NotNull(container);
            Assert.Equal(1, container.Elements.OfType<IEdmFunctionImport>().Count());
            IEdmFunctionImport action = container.Elements.OfType<IEdmFunctionImport>().Single();
            Assert.True(action.IsBindable);
            Assert.False(model.IsAlwaysBindable(action));
        }
예제 #25
0
 private static void BuildAction(ODataModelBuilder builder)
 {
     builder.Entity <ForeignKeyCustomer>().Collection.Action("ResetDataSource");
 }
예제 #26
0
        public void RedefiningBaseTypeProperty_Throws()
        {
            var builder = new ODataModelBuilder();

            builder
                .Entity<Vehicle>()
                .Property(v => v.WheelCount);

            Assert.Throws<InvalidOperationException>(
                () => builder
                        .Entity<Motorcycle>()
                        .DerivesFrom<Vehicle>()
                        .Property(m => m.WheelCount),
                "Cannot redefine property 'WheelCount' already defined on the base type 'System.Web.Http.OData.Builder.TestModels.Vehicle'.");
        }
예제 #27
0
        public void DefiningPropertyOnBaseTypeAlreadyPresentInDerivedType_Throws()
        {
            var builder = new ODataModelBuilder();

            builder
                .Entity<Motorcycle>()
                .DerivesFrom<Vehicle>()
                .Property(m => m.Model);

            Assert.Throws<InvalidOperationException>(
                () => builder
                        .Entity<Vehicle>()
                        .Property(v => v.Model),
                "Cannot define property 'Model' in the base entity type 'System.Web.Http.OData.Builder.TestModels.Vehicle' as the derived type 'System.Web.Http.OData.Builder.TestModels.Motorcycle' already defines it.");
        }
예제 #28
0
        public void DerivesFrom_Throws_IfDerivedTypeHasKeys()
        {
            var builder = new ODataModelBuilder();

            Assert.Throws<InvalidOperationException>(
            () => builder
                    .Entity<Motorcycle>()
                    .HasKey(m => m.Model)
                    .DerivesFrom<Vehicle>(),
            "Cannot define keys on type 'System.Web.Http.OData.Builder.TestModels.Motorcycle' deriving from 'System.Web.Http.OData.Builder.TestModels.Vehicle'. Only the root type in the entity inheritance hierarchy can contain keys.");
        }
예제 #29
0
        public void DerivesFrom_Throws_IfDerivedTypeDoesntDeriveFromBaseType()
        {
            var builder = new ODataModelBuilder();

            Assert.Throws<InvalidOperationException>(
                () => builder
                        .Entity<string>()
                        .DerivesFrom<Vehicle>(),
                "'System.String' does not inherit from 'System.Web.Http.OData.Builder.TestModels.Vehicle'.");
        }
예제 #30
0
        public void CannotDeriveFromItself()
        {
            var builder = new ODataModelBuilder();

            Assert.Throws<InvalidOperationException>(
            () => builder
                .Entity<Vehicle>()
                .DerivesFrom<Vehicle>(),
            "'System.Web.Http.OData.Builder.TestModels.Vehicle' does not inherit from 'System.Web.Http.OData.Builder.TestModels.Vehicle'.");
        }
        public void CanCreateFunctionWithCollectionReturnTypeViaEntitySetPath()
        {
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration<Customer> customer = builder.Entity<Customer>();
            EntityTypeConfiguration<Order> order = builder.Entity<Order>();

            customer.HasMany<Order>(c => c.Orders);
            FunctionConfiguration getOrders = customer.Function("GetOrders").ReturnsCollectionViaEntitySetPath<Order>("bindingParameter/Orders");
            IEdmModel model = builder.GetEdmModel();
            IEdmEntityContainer container = model.SchemaElements.OfType<IEdmEntityContainer>().SingleOrDefault();
            IEdmFunctionImport function = container.FindOperationImports("GetOrders").Single() as IEdmFunctionImport;

            // Assert
            Assert.NotNull(function);
            Assert.Equal(function.EntitySet.ExpressionKind, EdmExpressionKind.Path);
            Assert.Equal(string.Join("/", ((IEdmPathExpression)(function.EntitySet)).Path), "bindingParameter/Orders");
        }
        public void CanCreateEdmModel_WithBindableAction()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration<Customer> customer = builder.Entity<Customer>();
            customer.HasKey(c => c.CustomerId);
            customer.Property(c => c.Name);
            // Act
            ActionConfiguration sendEmail = customer.Action("ActionName");
            IEdmModel model = builder.GetEdmModel();

            // Assert
            IEdmEntityContainer container = model.EntityContainers().SingleOrDefault();
            Assert.NotNull(container);
            Assert.Equal(1, container.Elements.OfType<IEdmFunctionImport>().Count());
            IEdmFunctionImport action = container.Elements.OfType<IEdmFunctionImport>().Single();
            Assert.False(action.IsComposable);
            Assert.True(action.IsSideEffecting);
            Assert.True(action.IsBindable);
            Assert.True(model.IsAlwaysBindable(action));
            Assert.Equal("ActionName", action.Name);
            Assert.Null(action.ReturnType);
            Assert.Equal(1, action.Parameters.Count());
            Assert.Equal(BindingParameterConfiguration.DefaultBindingParameterName, action.Parameters.Single().Name);
            Assert.Equal(typeof(Customer).FullName, action.Parameters.Single().Type.FullName());
        }
예제 #33
0
        private static IEdmModel GetEdmModel()
        {
            ODataModelBuilder modelBuilder = new ODataModelBuilder();
            modelBuilder
                .Entity<DerivedTypeA>()
                .DerivesFrom<BaseType>();

            modelBuilder
                .Entity<DerivedTypeB>()
                .DerivesFrom<BaseType>();

            return modelBuilder.GetEdmModel();
        }
예제 #34
0
        private static IEdmModel GetEdmModel()
        {
            ODataModelBuilder builder = new ODataModelBuilder();

            builder
                .Entity<Vehicle>()
                .HasKey(v => v.Name)
                .HasKey(v => v.Model)
                .Property(v => v.WheelCount);

            builder
                .Entity<Motorcycle>()
                .DerivesFrom<Vehicle>()
                .Property(m => m.CanDoAWheelie);

            builder
                .Entity<Car>()
                .DerivesFrom<Vehicle>()
                .Property(c => c.SeatingCapacity);

            builder.EntitySet<Vehicle>("vehicles").HasIdLink(
                (v) => "http://localhost/vehicles/" + v.GetPropertyValue("Name"), followsConventions: false);
            builder.EntitySet<Motorcycle>("motorcycles").HasIdLink(
                (m) => "http://localhost/motorcycles/" + m.GetPropertyValue("Name"), followsConventions: false);
            builder.EntitySet<Car>("cars");

            builder
                .Action("GetCarAsVehicle")
                .ReturnsFromEntitySet<Vehicle>("vehicles");
            builder
                .Action("GetMotorcycleAsVehicle")
                .ReturnsFromEntitySet<Vehicle>("vehicles");
            builder
                .Action("GetSportBikeAsVehicle")
                .ReturnsFromEntitySet<Vehicle>("vehicles");
            builder
                .Action("GetVehicles")
                .ReturnsFromEntitySet<Vehicle>("vehicles");

            builder
                .Action("PatchMotorcycle_When_Expecting_Motorcycle")
                .ReturnsFromEntitySet<Motorcycle>("motorcycles");
            builder
                .Action("PostMotorcycle_When_Expecting_Motorcycle")
                .ReturnsFromEntitySet<Motorcycle>("motorcycles");
            builder
                .Action("PatchMotorcycle_When_Expecting_Vehicle")
                .ReturnsFromEntitySet<Vehicle>("vehicles");
            builder
                .Action("PostMotorcycle_When_Expecting_Vehicle")
                .ReturnsFromEntitySet<Vehicle>("vehicles");
            builder
                .Action("PostMotorcycle_When_Expecting_Car")
                .ReturnsFromEntitySet<Car>("cars");
            builder
                .Action("PatchMotorcycle_When_Expecting_Car")
                .ReturnsFromEntitySet<Car>("cars");

            return builder.GetEdmModel();
        }
예제 #35
0
        private static IEdmModel GetEdmModel()
        {
            ODataModelBuilder builder = new ODataModelBuilder();

            builder
                .Entity<Vehicle>()
                .HasKey(v => v.Name)
                .HasKey(v => v.Model)
                .Property(v => v.WheelCount);

            builder
                .Entity<Motorcycle>()
                .DerivesFrom<Vehicle>()
                .Property(m => m.CanDoAWheelie);

            builder
                .Entity<Car>()
                .DerivesFrom<Vehicle>()
                .Property(c => c.SeatingCapacity);

            builder.EntitySet<Vehicle>("vehicles");
            builder.EntitySet<Motorcycle>("motorcycles");
            builder.EntitySet<Car>("cars");

            return builder.GetEdmModel();
        }
        public void CanCreateTransientAction()
        {
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration<Customer> customer = builder.Entity<Customer>();
            customer.TransientAction("Reward");

            ProcedureConfiguration action = builder.Procedures.SingleOrDefault();
            Assert.NotNull(action);
            Assert.True(action.IsBindable);
            Assert.False(action.IsAlwaysBindable);
        }
예제 #37
0
 public static ODataModelBuilder Add_CustomerOrders_Relationship(this ODataModelBuilder builder)
 {
     builder.Entity <Customer>().HasMany(c => c.Orders);
     return(builder);
 }
        public void CanCreateEdmModel_WithTransientBindableAction()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration<Customer> customer = builder.Entity<Customer>();
            customer.HasKey(c => c.CustomerId);
            customer.Property(c => c.Name);

            // Act
            ActionConfiguration sendEmail = customer.TransientAction("ActionName");
            IEdmModel model = builder.GetEdmModel();

            // Assert
            IEdmAction action = Assert.Single(model.SchemaElements.OfType<IEdmAction>());
            Assert.True(action.IsBound);
            Assert.False(model.IsAlwaysBindable(action));
        }
예제 #39
0
 public static ODataModelBuilder Add_OrderCustomer_Relationship(this ODataModelBuilder builder)
 {
     builder.Entity <Order>().HasRequired(o => o.Customer);
     return(builder);
 }
        /// <summary>
        /// Generates a model explicitly.
        /// </summary>
        /// <returns></returns>
        static IEdmModel GetExplicitEdmModel()
        {
            ODataModelBuilder modelBuilder = new ODataModelBuilder();

            var products = modelBuilder.EntitySet <Product>("Products");

            products.HasEditLink(
                entityContext =>
            {
                object id;
                entityContext.EdmObject.TryGetPropertyValue("ID", out id);
                return(entityContext.Url.ODataLink(
                           new EntitySetPathSegment(entityContext.EntitySet.Name),
                           new KeyValuePathSegment(ODataUriUtils.ConvertToUriLiteral(id, ODataVersion.V3))));
            },
                followsConventions: true);

            var suppliers = modelBuilder.EntitySet <Supplier>("Suppliers");

            suppliers.HasEditLink(
                entityContext =>
            {
                object id;
                entityContext.EdmObject.TryGetPropertyValue("ID", out id);
                return(entityContext.Url.ODataLink(
                           new EntitySetPathSegment(entityContext.EntitySet.Name),
                           new KeyValuePathSegment(ODataUriUtils.ConvertToUriLiteral(id, ODataVersion.V3))));
            },
                followsConventions: true);

            var families = modelBuilder.EntitySet <ProductFamily>("ProductFamilies");

            families.HasEditLink(
                entityContext =>
            {
                object id;
                entityContext.EdmObject.TryGetPropertyValue("ID", out id);
                return(entityContext.Url.ODataLink(
                           new EntitySetPathSegment(entityContext.EntitySet.Name),
                           new KeyValuePathSegment(ODataUriUtils.ConvertToUriLiteral(id, ODataVersion.V3))));
            },
                followsConventions: true);

            var product = products.EntityType;

            product.HasKey(p => p.ID);
            product.Property(p => p.Name);
            product.Property(p => p.ReleaseDate);
            product.Property(p => p.SupportedUntil);

            modelBuilder.Entity <RatedProduct>().DerivesFrom <Product>().Property(rp => rp.Rating);

            var address = modelBuilder.ComplexType <Address>();

            address.Property(a => a.City);
            address.Property(a => a.Country);
            address.Property(a => a.State);
            address.Property(a => a.Street);
            address.Property(a => a.ZipCode);

            var supplier = suppliers.EntityType;

            supplier.HasKey(s => s.ID);
            supplier.Property(s => s.Name);
            supplier.ComplexProperty(s => s.Address);

            var productFamily = families.EntityType;

            productFamily.HasKey(pf => pf.ID);
            productFamily.Property(pf => pf.Name);
            productFamily.Property(pf => pf.Description);

            // Create relationships and bindings in one go
            products.HasRequiredBinding(p => p.Family, families);
            families.HasManyBinding(pf => pf.Products, products);
            families.HasOptionalBinding(pf => pf.Supplier, suppliers);
            suppliers.HasManyBinding(s => s.ProductFamilies, families);

            // Create navigation Link builders
            products.HasNavigationPropertiesLink(
                product.NavigationProperties,
                (entityContext, navigationProperty) =>
            {
                object id;
                entityContext.EdmObject.TryGetPropertyValue("ID", out id);
                return(new Uri(entityContext.Url.ODataLink(
                                   new EntitySetPathSegment(entityContext.EntitySet.Name),
                                   new KeyValuePathSegment(ODataUriUtils.ConvertToUriLiteral(id, ODataVersion.V3)),
                                   new NavigationPathSegment(navigationProperty.Name))));
            },
                followsConventions: true);

            families.HasNavigationPropertiesLink(
                productFamily.NavigationProperties,
                (entityContext, navigationProperty) =>
            {
                object id;
                entityContext.EdmObject.TryGetPropertyValue("ID", out id);
                return(new Uri(entityContext.Url.ODataLink(
                                   new EntitySetPathSegment(entityContext.EntitySet.Name),
                                   new KeyValuePathSegment(ODataUriUtils.ConvertToUriLiteral(id, ODataVersion.V3)),
                                   new NavigationPathSegment(navigationProperty.Name))));
            },
                followsConventions: true);

            suppliers.HasNavigationPropertiesLink(
                supplier.NavigationProperties,
                (entityContext, navigationProperty) =>
            {
                object id;
                entityContext.EdmObject.TryGetPropertyValue("ID", out id);
                return(new Uri(entityContext.Url.ODataLink(
                                   new EntitySetPathSegment(entityContext.EntitySet.Name),
                                   new KeyValuePathSegment(ODataUriUtils.ConvertToUriLiteral(id, ODataVersion.V3)),
                                   new NavigationPathSegment(navigationProperty.Name))));
            },
                followsConventions: true);

            ActionConfiguration createProduct = product.Action("CreateProduct");

            createProduct.Parameter <string>("Name");
            createProduct.Returns <int>();

            return(modelBuilder.GetEdmModel());
        }
예제 #41
0
        public void CanDefinePropertyOnDerivedType_NotPresentInBaseEdmType_ButPresentInBaseClrType()
        {
            var builder = new ODataModelBuilder();

            builder
                .Entity<Motorcycle>()
                .DerivesFrom<Vehicle>()
                .Property(m => m.Model);

            var model = builder.GetEdmModel();

            var edmVehicle = model.AssertHasEntityType(typeof(Vehicle));
            Assert.Null(edmVehicle.BaseEntityType());
            Assert.Equal(0, edmVehicle.Properties().Count());

            var edmMotorcycle = model.AssertHasEntityType(typeof(Motorcycle));
            Assert.Equal(edmVehicle, edmMotorcycle.BaseEntityType());
            Assert.Equal(1, edmMotorcycle.Properties().Count());
            edmMotorcycle.AssertHasPrimitiveProperty(model, "Model", EdmPrimitiveTypeKind.Int32, isNullable: false);
        }
예제 #42
0
        public static IEdmModel GetExplicitModel(bool foreignKey)
        {
            ODataModelBuilder builder = new ODataModelBuilder();
            var customer = builder.Entity <ForeignKeyCustomer>();

            customer.HasKey(c => c.Id);
            customer.Property(c => c.Name);
            customer.HasMany(c => c.Orders);

            var order = builder.Entity <ForeignKeyOrder>();

            order.HasKey(o => o.OrderId);
            order.Property(o => o.OrderName);
            order.Property(o => o.CustomerId);

            EntitySetConfiguration <ForeignKeyCustomer> customers;
            EntitySetConfiguration <ForeignKeyOrder>    orders;

            if (foreignKey)
            {
                order.HasRequired(o => o.Customer, (o, c) => o.CustomerId == c.Id).CascadeOnDelete(cascade: true);

                customers = builder.EntitySet <ForeignKeyCustomer>("ForeignKeyCustomers");
                orders    = builder.EntitySet <ForeignKeyOrder>("ForeignKeyOrders");
                customers.HasManyBinding(c => c.Orders, "ForeignKeyOrders");
                orders.HasRequiredBinding(o => o.Customer, "ForeignKeyCustomers");
            }
            else
            {
                order.HasRequired(o => o.Customer);

                customers = builder.EntitySet <ForeignKeyCustomer>("ForeignKeyCustomersNoCascade");
                orders    = builder.EntitySet <ForeignKeyOrder>("ForeignKeyOrdersNoCascade");
                customers.HasManyBinding(c => c.Orders, "ForeignKeyOrdersNoCascade");
                orders.HasRequiredBinding(o => o.Customer, "ForeignKeyCustomersNoCascade");
            }

            customers.HasIdLink(entityContext =>
            {
                object id;
                entityContext.EdmObject.TryGetPropertyValue("Id", out id);
                return(entityContext.Url.Link("DefaultRouteName", new
                {
                    odataPath = entityContext.Url.CreateODataLink(
                        new EntitySetPathSegment(entityContext.EntitySet.Name),
                        new KeyValuePathSegment(id.ToString()))
                }));
            }, true);

            orders.HasIdLink(entityContext =>
            {
                object id;
                entityContext.EdmObject.TryGetPropertyValue("OrderId", out id);
                return(entityContext.Url.Link("DefaultRouteName", new
                {
                    odataPath = entityContext.Url.CreateODataLink(
                        new EntitySetPathSegment(entityContext.EntitySet.Name),
                        new KeyValuePathSegment(id.ToString()))
                }));
            }, true);

            // Create navigation Link builders
            customers.HasNavigationPropertiesLink(
                customer.NavigationProperties,
                (entityContext, navigationProperty) =>
            {
                object id;
                entityContext.EdmObject.TryGetPropertyValue("Id", out id);
                return(new Uri(entityContext.Url.Link("DefaultRouteName",
                                                      new
                {
                    odataPath = entityContext.Url.CreateODataLink(
                        new EntitySetPathSegment(entityContext.EntitySet.Name),
                        new KeyValuePathSegment(id.ToString()),
                        new NavigationPathSegment(navigationProperty))
                })));
            }, true);

            orders.HasNavigationPropertiesLink(
                order.NavigationProperties,
                (entityContext, navigationProperty) =>
            {
                object id;
                entityContext.EdmObject.TryGetPropertyValue("OrderId", out id);
                return(new Uri(entityContext.Url.Link("DefaultRouteName",
                                                      new
                {
                    odataPath = entityContext.Url.CreateODataLink(
                        new EntitySetPathSegment(entityContext.EntitySet.Name),
                        new KeyValuePathSegment(id.ToString()),
                        new NavigationPathSegment(navigationProperty))
                })));
            }, true);

            BuildAction(builder);

            return(builder.GetEdmModel());
        }
예제 #43
0
        public void DerivesFrom_Throws_WhenSettingTheBaseType_IfDuplicatePropertyInBaseType()
        {
            var builder = new ODataModelBuilder();

            builder
                .Entity<Vehicle>()
                .Property(v => v.Model);

            var motorcycle = builder
                            .Entity<Motorcycle>();
            motorcycle.Property(m => m.Model);

            Assert.Throws<InvalidOperationException>(
                () => motorcycle.DerivesFrom<Vehicle>(),
                "Cannot redefine property 'Model' already defined on the base type 'System.Web.Http.OData.Builder.TestModels.Vehicle'.");
        }