Пример #1
0
        private static void TrackEntitiesTest(
            Func<DbSet<Category>, Category, EntityEntry<Category>> categoryAdder,
            Func<DbSet<Product>, Product, EntityEntry<Product>> productAdder, EntityState expectedState)
        {
            using (var context = new EarlyLearningCenter())
            {
                var category1 = new Category { Id = 1, Name = "Beverages" };
                var category2 = new Category { Id = 2, Name = "Foods" };
                var product1 = new Product { Id = 1, Name = "Marmite", Price = 7.99m };
                var product2 = new Product { Id = 2, Name = "Bovril", Price = 4.99m };

                var categoryEntry1 = categoryAdder(context.Categories, category1);
                var categoryEntry2 = categoryAdder(context.Categories, category2);
                var productEntry1 = productAdder(context.Products, product1);
                var productEntry2 = productAdder(context.Products, product2);

                Assert.Same(category1, categoryEntry1.Entity);
                Assert.Same(category2, categoryEntry2.Entity);
                Assert.Same(product1, productEntry1.Entity);
                Assert.Same(product2, productEntry2.Entity);

                Assert.Same(category1, categoryEntry1.Entity);
                Assert.Equal(expectedState, categoryEntry2.State);
                Assert.Same(category2, categoryEntry2.Entity);
                Assert.Equal(expectedState, categoryEntry2.State);

                Assert.Same(product1, productEntry1.Entity);
                Assert.Equal(expectedState, productEntry1.State);
                Assert.Same(product2, productEntry2.Entity);
                Assert.Equal(expectedState, productEntry2.State);

                Assert.Same(categoryEntry1.GetInfrastructure(), context.Entry(category1).GetInfrastructure());
                Assert.Same(categoryEntry2.GetInfrastructure(), context.Entry(category2).GetInfrastructure());
                Assert.Same(productEntry1.GetInfrastructure(), context.Entry(product1).GetInfrastructure());
                Assert.Same(productEntry2.GetInfrastructure(), context.Entry(product2).GetInfrastructure());
            }
        }
Пример #2
0
        public void Can_attach_entity_with_one_to_one_parent_and_child()
        {
            using (var context = new EarlyLearningCenter())
            {
                var details = new ProductDetails {
                    Id = 1, Product = new Product {
                        Id = 1
                    }, Tag = new ProductDetailsTag {
                        Id = 1
                    }
                };

                context.ChangeTracker.AttachGraph(details, e => e.SetState(EntityState.Unchanged));

                Assert.Equal(3, context.ChangeTracker.Entries().Count());

                Assert.Equal(EntityState.Unchanged, context.Entry(details).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(details.Product).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(details.Tag).State);

                Assert.Same(details, details.Tag.Details);
                Assert.Same(details, details.Product.Details);
            }
        }
Пример #3
0
        public void Can_attach_child_with_one_to_one_parents()
        {
            using (var context = new EarlyLearningCenter())
            {
                var tag = new ProductDetailsTag {
                    Id = 1, Details = new ProductDetails {
                        Id = 1, Product = new Product {
                            Id = 1
                        }
                    }
                };

                context.ChangeTracker.TrackGraph(tag, e => e.State = EntityState.Unchanged);

                Assert.Equal(3, context.ChangeTracker.Entries().Count());

                Assert.Equal(EntityState.Unchanged, context.Entry(tag).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(tag.Details).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(tag.Details.Product).State);

                Assert.Same(tag, tag.Details.Tag);
                Assert.Same(tag.Details, tag.Details.Product.Details);
            }
        }
Пример #4
0
        private void ChangeStateWithMethod(Action <EarlyLearningCenter, Category> action, EntityState initialState, EntityState expectedState)
        {
            using (var context = new EarlyLearningCenter())
            {
                var entity = new Category {
                    Id = 1, Name = "Beverages"
                };
                var entry = context.Entry(entity);

                entry.State = initialState;

                action(context, entity);

                Assert.Equal(expectedState, entry.State);
            }
        }
Пример #5
0
        private async Task ChangeStateWithMethod(
            Func <EarlyLearningCenter, Category, Task> action,
            EntityState initialState,
            EntityState expectedState)
        {
            using var context = new EarlyLearningCenter();
            var entity = new Category {
                Id = 1, Name = "Beverages"
            };
            var entry = context.Entry(entity);

            entry.State = initialState;

            await action(context, entity);

            Assert.Equal(expectedState, entry.State);
        }
Пример #6
0
        private static void TrackEntitiesWithKeyGenerationTest(Func<DbContext, TheGu, TheGu> adder)
        {
            using (var context = new EarlyLearningCenter(TestHelpers.Instance.CreateServiceProvider()))
            {
                var gu1 = new TheGu { ShirtColor = "Red" };
                var gu2 = new TheGu { ShirtColor = "Still Red" };

                Assert.Same(gu1, adder(context, gu1));
                Assert.Same(gu2, adder(context, gu2));
                Assert.NotEqual(default(Guid), gu1.Id);
                Assert.NotEqual(default(Guid), gu2.Id);
                Assert.NotEqual(gu1.Id, gu2.Id);

                var categoryEntry = context.Entry(gu1);
                Assert.Same(gu1, categoryEntry.Entity);
                Assert.Equal(EntityState.Added, categoryEntry.State);

                categoryEntry = context.Entry(gu2);
                Assert.Same(gu2, categoryEntry.Entity);
                Assert.Equal(EntityState.Added, categoryEntry.State);
            }
        }
Пример #7
0
        private static void TrackEntitiesTestNonGeneric(
            Func<DbContext, object, EntityEntry> categoryAdder,
            Func<DbContext, object, EntityEntry> productAdder, EntityState expectedState)
        {
            using (var context = new EarlyLearningCenter(TestHelpers.Instance.CreateServiceProvider()))
            {
                var category1 = new Category { Id = 1, Name = "Beverages" };
                var category2 = new Category { Id = 2, Name = "Foods" };
                var product1 = new Product { Id = 1, Name = "Marmite", Price = 7.99m };
                var product2 = new Product { Id = 2, Name = "Bovril", Price = 4.99m };

                var categoryEntry1 = categoryAdder(context, category1);
                var categoryEntry2 = categoryAdder(context, category2);
                var productEntry1 = productAdder(context, product1);
                var productEntry2 = productAdder(context, product2);

                Assert.Same(category1, categoryEntry1.Entity);
                Assert.Same(category2, categoryEntry2.Entity);
                Assert.Same(product1, productEntry1.Entity);
                Assert.Same(product2, productEntry2.Entity);

                Assert.Same(category1, categoryEntry1.Entity);
                Assert.Equal(expectedState, categoryEntry2.State);
                Assert.Same(category2, categoryEntry2.Entity);
                Assert.Equal(expectedState, categoryEntry2.State);

                Assert.Same(product1, productEntry1.Entity);
                Assert.Equal(expectedState, productEntry1.State);
                Assert.Same(product2, productEntry2.Entity);
                Assert.Equal(expectedState, productEntry2.State);

                Assert.Same(categoryEntry1.GetInfrastructure(), context.Entry(category1).GetInfrastructure());
                Assert.Same(categoryEntry2.GetInfrastructure(), context.Entry(category2).GetInfrastructure());
                Assert.Same(productEntry1.GetInfrastructure(), context.Entry(product1).GetInfrastructure());
                Assert.Same(productEntry2.GetInfrastructure(), context.Entry(product2).GetInfrastructure());
            }
        }
Пример #8
0
        public void Entry_methods_check_arguments()
        {
            var services = new ServiceCollection()
                .AddScoped<IStateManager, FakeStateManager>();

            var serviceProvider = TestHelpers.Instance.CreateServiceProvider(services);

            using (var context = new EarlyLearningCenter(serviceProvider))
            {
                Assert.Equal(
                    "entity",
                    // ReSharper disable once AssignNullToNotNullAttribute
                    Assert.Throws<ArgumentNullException>(() => context.Entry(null)).ParamName);
                Assert.Equal(
                    "entity",
                    // ReSharper disable once AssignNullToNotNullAttribute
                    Assert.Throws<ArgumentNullException>(() => context.Entry<Random>(null)).ParamName);
            }
        }
Пример #9
0
        public void SaveChanges_doesnt_call_Database_when_nothing_is_dirty()
        {
            var database = new Mock<IDatabase>();

            var servicesMock = new Mock<IDatabaseProviderServices>();
            servicesMock.Setup(m => m.Database).Returns(database.Object);
            servicesMock.Setup(m => m.ModelSource).Returns(new Mock<ModelSource>(new DbSetFinder(), new CoreConventionSetBuilder())
                { CallBase = true }.Object);
            servicesMock
                .Setup(m => m.ModelValidator)
                .Returns(new LoggingModelValidator(new Logger<LoggingModelValidator>(new LoggerFactory())));

            var sourceMock = new Mock<IDatabaseProvider>();
            sourceMock.Setup(m => m.IsConfigured(It.IsAny<IDbContextOptions>())).Returns(true);
            sourceMock.Setup(m => m.GetProviderServices(It.IsAny<IServiceProvider>())).Returns(servicesMock.Object);

            var services = new ServiceCollection();
            services.AddEntityFramework();
            services.AddInstance(sourceMock.Object);
            var serviceProvider = services.BuildServiceProvider();

            using (var context = new EarlyLearningCenter(serviceProvider, new DbContextOptionsBuilder().Options))
            {
                context.Entry(new Category { Id = 1 }).State = EntityState.Unchanged;
                context.Entry(new Category { Id = 2 }).State = EntityState.Unchanged;
                Assert.Equal(2, context.ChangeTracker.Entries().Count());

                context.SaveChanges();
            }

            database.Verify(
                s => s.SaveChangesAsync(It.IsAny<IReadOnlyList<InternalEntityEntry>>(), It.IsAny<CancellationToken>()),
                Times.Never);
        }
Пример #10
0
        [Fact] // Issue #1246
        public void Can_set_set_to_Unchanged_with_inconsistent_FK_dependent_first_collection_not_fixed_up()
        {
            using (var context = new EarlyLearningCenter(TestHelpers.Instance.CreateServiceProvider()))
            {
                var category = new Category { Id = 1, Name = "Beverages" };
                var product = new Product { Id = 1, CategoryId = 7, Name = "Marmite", Category = category };
                category.Products = new List<Product>();

                context.Entry(product).State = EntityState.Unchanged;

                Assert.Equal(7, product.CategoryId);
                Assert.Empty(category.Products);
                Assert.Same(category, product.Category);
                Assert.Equal(EntityState.Detached, context.Entry(category).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(product).State);

                context.Entry(category).State = EntityState.Unchanged;

                Assert.Equal(7, product.CategoryId);
                Assert.Empty(category.Products);
                Assert.Same(category, product.Category);
                Assert.Equal(EntityState.Unchanged, context.Entry(category).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(product).State);
            }
        }
Пример #11
0
        public void SaveChanges_only_passes_dirty_entries_to_DataStore()
        {
            var passedEntries = new List<InternalEntityEntry>();
            var store = new Mock<IDataStore>();
            store.Setup(s => s.SaveChanges(It.IsAny<IReadOnlyList<InternalEntityEntry>>()))
                .Callback<IEnumerable<InternalEntityEntry>>(passedEntries.AddRange)
                .Returns(3);

            var valueGenMock = new Mock<IValueGeneratorSelector>();
            valueGenMock.Setup(m => m.Select(It.IsAny<IProperty>())).Returns(Mock.Of<ValueGenerator>());

            var servicesMock = new Mock<IDataStoreServices>();
            servicesMock.Setup(m => m.Store).Returns(store.Object);
            servicesMock.Setup(m => m.ValueGeneratorSelector).Returns(valueGenMock.Object);
            servicesMock.Setup(m => m.ModelBuilderFactory).Returns(new ModelBuilderFactory());
            servicesMock.Setup(m => m.ModelSource).Returns(new Mock<ModelSource>(new DbSetFinder(), Mock.Of<IModelValidator>())
                { CallBase = true }.Object);

            var sourceMock = new Mock<IDataStoreSource>();
            sourceMock.Setup(m => m.IsConfigured(It.IsAny<IDbContextOptions>())).Returns(true);
            sourceMock.Setup(m => m.GetStoreServices(It.IsAny<IServiceProvider>())).Returns(servicesMock.Object);

            var services = new ServiceCollection();
            services.AddEntityFramework();
            services.AddInstance(sourceMock.Object);
            var serviceProvider = services.BuildServiceProvider();

            using (var context = new EarlyLearningCenter(serviceProvider, new DbContextOptionsBuilder().Options))
            {
                context.Entry(new Category { Id = 1 }).State = EntityState.Unchanged;
                context.Entry(new Category { Id = 2 }).State = EntityState.Modified;
                context.Entry(new Category { Id = 3 }).State = EntityState.Added;
                context.Entry(new Category { Id = 4 }).State = EntityState.Deleted;
                Assert.Equal(4, context.ChangeTracker.Entries().Count());

                context.SaveChanges();
            }

            Assert.Equal(3, passedEntries.Count);

            store.Verify(
                s => s.SaveChanges(It.IsAny<IReadOnlyList<InternalEntityEntry>>()),
                Times.Once);
        }
Пример #12
0
        [Fact] // Issue #1246
        public void Can_attach_with_inconsistent_FK_principal_first_reference_not_fixed_up_with_tracked_FK_match()
        {
            using (var context = new EarlyLearningCenter(TestHelpers.Instance.CreateServiceProvider()))
            {
                var category7 = context.Attach(new Category { Id = 7, Products = new List<Product>() }).Entity;

                var category = new Category { Id = 1, Name = "Beverages" };
                var product = new Product { Id = 1, CategoryId = 7, Name = "Marmite" };
                category.Products = new List<Product> { product };

                context.Attach(category);

                Assert.Equal(1, product.CategoryId);
                Assert.Same(product, category.Products.Single());
                Assert.Same(category, product.Category);
                Assert.Empty(category7.Products);
                Assert.Equal(EntityState.Unchanged, context.Entry(category).State);
                Assert.Equal(EntityState.Detached, context.Entry(product).State);

                context.Attach(product);

                Assert.Equal(1, product.CategoryId);
                Assert.Same(product, category.Products.Single());
                Assert.Same(category, product.Category);
                Assert.Empty(category7.Products);
                Assert.Equal(EntityState.Unchanged, context.Entry(category).State);

                // Dependent is Unchanged here because the FK change happened before it was attached
                Assert.Equal(EntityState.Unchanged, context.Entry(product).State);
            }
        }
Пример #13
0
        private static void TrackMultipleEntitiesTest(
            Action <EarlyLearningCenter, Category[]> categoryAdder,
            Action <EarlyLearningCenter, Product[]> productAdder, EntityState expectedState)
        {
            using (var context = new EarlyLearningCenter())
            {
                var category1 = new Category {
                    Id = 1, Name = "Beverages"
                };
                var category2 = new Category {
                    Id = 2, Name = "Foods"
                };
                var product1 = new Product {
                    Id = 1, Name = "Marmite", Price = 7.99m
                };
                var product2 = new Product {
                    Id = 2, Name = "Bovril", Price = 4.99m
                };

                categoryAdder(context, new[] { category1, category2 });
                productAdder(context, new[] { product1, product2 });

                Assert.Same(category1, context.Entry(category1).Entity);
                Assert.Same(category2, context.Entry(category2).Entity);
                Assert.Same(product1, context.Entry(product1).Entity);
                Assert.Same(product2, context.Entry(product2).Entity);

                Assert.Same(category1, context.Entry(category1).Entity);
                Assert.Equal(expectedState, context.Entry(category1).State);
                Assert.Same(category2, context.Entry(category2).Entity);
                Assert.Equal(expectedState, context.Entry(category2).State);

                Assert.Same(product1, context.Entry(product1).Entity);
                Assert.Equal(expectedState, context.Entry(product1).State);
                Assert.Same(product2, context.Entry(product2).Entity);
                Assert.Equal(expectedState, context.Entry(product2).State);
            }
        }
Пример #14
0
        private void ChangeStateWithMethod(Action<EarlyLearningCenter, Category> action, EntityState initialState, EntityState expectedState)
        {
            using (var context = new EarlyLearningCenter())
            {
                var entity = new Category { Id = 1, Name = "Beverages" };
                var entry = context.Entry(entity);

                entry.State = initialState;

                action(context, entity);

                Assert.Equal(expectedState, entry.State);
            }
        }
Пример #15
0
        [Fact] // Issue #1246
        public void Can_attach_with_inconsistent_FK_dependent_first_reference_not_fixed_up()
        {
            using (var context = new EarlyLearningCenter(TestHelpers.Instance.CreateServiceProvider()))
            {
                var category = new Category { Id = 1, Name = "Beverages" };
                var product = new Product { Id = 1, CategoryId = 7, Name = "Marmite" };
                category.Products = new List<Product> { product };

                context.Attach(product, behavior: GraphBehavior.SingleObject);

                Assert.Equal(7, product.CategoryId);
                Assert.Same(product, category.Products.Single());
                Assert.Null(product.Category);
                Assert.Equal(EntityState.Detached, context.Entry(category).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(product).State);

                context.Attach(category, behavior: GraphBehavior.SingleObject);

                Assert.Equal(7, product.CategoryId);
                Assert.Same(product, category.Products.Single());
                Assert.Null(product.Category);
                Assert.Equal(EntityState.Unchanged, context.Entry(category).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(product).State);
            }
        }
Пример #16
0
        private static void TrackMultipleEntitiesTest(
            Action<EarlyLearningCenter, Category[]> categoryAdder,
            Action<EarlyLearningCenter, Product[]> productAdder, EntityState expectedState)
        {
            using (var context = new EarlyLearningCenter())
            {
                var category1 = new Category { Id = 1, Name = "Beverages" };
                var category2 = new Category { Id = 2, Name = "Foods" };
                var product1 = new Product { Id = 1, Name = "Marmite", Price = 7.99m };
                var product2 = new Product { Id = 2, Name = "Bovril", Price = 4.99m };

                categoryAdder(context, new[] { category1, category2 });
                productAdder(context, new[] { product1, product2 });

                Assert.Same(category1, context.Entry(category1).Entity);
                Assert.Same(category2, context.Entry(category2).Entity);
                Assert.Same(product1, context.Entry(product1).Entity);
                Assert.Same(product2, context.Entry(product2).Entity);

                Assert.Same(category1, context.Entry(category1).Entity);
                Assert.Equal(expectedState, context.Entry(category1).State);
                Assert.Same(category2, context.Entry(category2).Entity);
                Assert.Equal(expectedState, context.Entry(category2).State);

                Assert.Same(product1, context.Entry(product1).Entity);
                Assert.Equal(expectedState, context.Entry(product1).State);
                Assert.Same(product2, context.Entry(product2).Entity);
                Assert.Equal(expectedState, context.Entry(product2).State);
            }
        }
        public void Can_attach_child_with_reference_to_parent()
        {
            using (var context = new EarlyLearningCenter())
            {
                var product = new Product { Id = 1, Category = new Category { Id = 1 } };

                context.ChangeTracker.TrackGraph(product, e => e.State = EntityState.Modified);

                Assert.Equal(2, context.ChangeTracker.Entries().Count());

                Assert.Equal(EntityState.Modified, context.Entry(product).State);
                Assert.Equal(EntityState.Modified, context.Entry(product.Category).State);

                Assert.Same(product, product.Category.Products[0]);
                Assert.Equal(product.Category.Id, product.CategoryId);
            }
        }
Пример #18
0
        [Fact] // Issue #1246
        public void Can_set_set_to_Unchanged_with_inconsistent_FK_dependent_first_fully_fixed_up_with_tracked_FK_match()
        {
            using (var context = new EarlyLearningCenter(TestHelpers.Instance.CreateServiceProvider()))
            {
                var category7 = context.Attach(new Category { Id = 7, Products = new List<Product>() }).Entity;

                var category = new Category { Id = 1, Name = "Beverages" };
                var product = new Product { Id = 1, CategoryId = 7, Name = "Marmite", Category = category };
                category.Products = new List<Product> { product };

                context.Entry(product).State = EntityState.Unchanged;

                Assert.Equal(1, product.CategoryId);
                Assert.Same(product, category.Products.Single());
                Assert.Same(category, product.Category);
                Assert.Empty(category7.Products);
                Assert.Equal(EntityState.Detached, context.Entry(category).State);
                Assert.Equal(EntityState.Modified, context.Entry(product).State);

                context.Entry(category).State = EntityState.Unchanged;

                Assert.Equal(1, product.CategoryId);
                Assert.Same(product, category.Products.Single());
                Assert.Same(category, product.Category);
                Assert.Empty(category7.Products);
                Assert.Equal(EntityState.Unchanged, context.Entry(category).State);
                Assert.Equal(EntityState.Modified, context.Entry(product).State);
            }
        }
        public void Can_attach_entity_with_one_to_one_parent_and_child()
        {
            using (var context = new EarlyLearningCenter())
            {
                var details = new ProductDetails { Id = 1, Product = new Product { Id = 1 }, Tag = new ProductDetailsTag { Id = 1 } };

                context.ChangeTracker.TrackGraph(details, e => e.State = EntityState.Unchanged);

                Assert.Equal(3, context.ChangeTracker.Entries().Count());

                Assert.Equal(EntityState.Unchanged, context.Entry(details).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(details.Product).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(details.Tag).State);

                Assert.Same(details, details.Tag.Details);
                Assert.Same(details, details.Product.Details);
            }
        }
Пример #20
0
        private static void TrackEntitiesTest(
            Func<DbContext, Category, EntityEntry<Category>> categoryAdder,
            Func<DbContext, Product, EntityEntry<Product>> productAdder, EntityState expectedState)
        {
            using (var context = new EarlyLearningCenter(TestHelpers.Instance.CreateServiceProvider()))
            {
                var category1 = new Category { Id = 1, Name = "Beverages" };
                var category2 = new Category { Id = 2, Name = "Foods" };
                var product1 = new Product { Id = 1, Name = "Marmite", Price = 7.99m };
                var product2 = new Product { Id = 2, Name = "Bovril", Price = 4.99m };

                var categoryEntry1 = categoryAdder(context, category1);
                var categoryEntry2 = categoryAdder(context, category2);
                var productEntry1 = productAdder(context, product1);
                var productEntry2 = productAdder(context, product2);

                Assert.Same(category1, categoryEntry1.Entity);
                Assert.Same(category2, categoryEntry2.Entity);
                Assert.Same(product1, productEntry1.Entity);
                Assert.Same(product2, productEntry2.Entity);

                Assert.Same(category1, categoryEntry1.Entity);
                Assert.Equal(expectedState, categoryEntry2.State);
                Assert.Same(category2, categoryEntry2.Entity);
                Assert.Equal(expectedState, categoryEntry2.State);

                Assert.Same(product1, productEntry1.Entity);
                Assert.Equal(expectedState, productEntry1.State);
                Assert.Same(product2, productEntry2.Entity);
                Assert.Equal(expectedState, productEntry2.State);

                Assert.Same(((IAccessor<InternalEntityEntry>)categoryEntry1).Service, ((IAccessor<InternalEntityEntry>)context.Entry(category1)).Service);
                Assert.Same(((IAccessor<InternalEntityEntry>)categoryEntry2).Service, ((IAccessor<InternalEntityEntry>)context.Entry(category2)).Service);
                Assert.Same(((IAccessor<InternalEntityEntry>)productEntry1).Service, ((IAccessor<InternalEntityEntry>)context.Entry(product1)).Service);
                Assert.Same(((IAccessor<InternalEntityEntry>)productEntry2).Service, ((IAccessor<InternalEntityEntry>)context.Entry(product2)).Service);
            }
        }
        public void Entities_that_are_already_tracked_will_not_get_attached()
        {
            using (var context = new EarlyLearningCenter())
            {
                var existingProduct = context.Attach(new Product { Id = 2, CategoryId = 1 }).Entity;

                var category = new Category
                    {
                        Id = 1,
                        Products = new List<Product>
                            {
                                new Product { Id = 1 },
                                existingProduct,
                                new Product { Id = 3 }
                            }
                    };

                context.ChangeTracker.TrackGraph(category, e => e.State = EntityState.Modified);

                Assert.Equal(4, context.ChangeTracker.Entries().Count());

                Assert.Equal(EntityState.Modified, context.Entry(category).State);
                Assert.Equal(EntityState.Modified, context.Entry(category.Products[0]).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(category.Products[1]).State);
                Assert.Equal(EntityState.Modified, context.Entry(category.Products[2]).State);

                Assert.Same(category, category.Products[0].Category);
                Assert.Same(category, category.Products[1].Category);
                Assert.Same(category, category.Products[2].Category);

                Assert.Equal(category.Id, category.Products[0].CategoryId);
                Assert.Equal(category.Id, category.Products[1].CategoryId);
                Assert.Equal(category.Id, category.Products[2].CategoryId);
            }
        }
Пример #22
0
        [Fact] // Issue #1246
        public void Can_set_set_to_Unchanged_with_inconsistent_FK_principal_first_reference_not_fixed_up_with_tracked_FK_match()
        {
            using (var context = new EarlyLearningCenter(TestHelpers.Instance.CreateServiceProvider()))
            {
                var category7 = context.Attach(new Category { Id = 7, Products = new List<Product>() }, behavior: GraphBehavior.SingleObject).Entity;

                var category = new Category { Id = 1, Name = "Beverages" };
                var product = new Product { Id = 1, CategoryId = 7, Name = "Marmite" };
                category.Products = new List<Product> { product };

                context.Entry(category).State = EntityState.Unchanged;

                Assert.Equal(7, product.CategoryId);
                Assert.Same(product, category.Products.Single());
                Assert.Null(product.Category);
                Assert.Empty(category7.Products);
                Assert.Equal(EntityState.Unchanged, context.Entry(category).State);
                Assert.Equal(EntityState.Detached, context.Entry(product).State);

                context.Entry(product).State = EntityState.Unchanged;

                Assert.Equal(7, product.CategoryId);
                Assert.Same(product, category.Products.Single());
                Assert.Same(category7, product.Category);
                Assert.Same(product, category7.Products.Single());
                Assert.Equal(EntityState.Unchanged, context.Entry(category).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(product).State);
            }
        }
        public void Further_graph_traversal_stops_if_an_entity_is_not_attached()
        {
            using (var context = new EarlyLearningCenter())
            {
                var category = new Category
                    {
                        Id = 1,
                        Products = new List<Product>
                            {
                                new Product { Id = 1, Details = new ProductDetails { Id = 1 } },
                                new Product { Id = 2, Details = new ProductDetails { Id = 2 } },
                                new Product { Id = 3, Details = new ProductDetails { Id = 3 } }
                            }
                    };

                context.ChangeTracker.TrackGraph(category, e =>
                    {
                        var product = e.Entity as Product;
                        if (product == null
                            || product.Id != 2)
                        {
                            e.State = EntityState.Unchanged;
                        }
                    });

                Assert.Equal(5, context.ChangeTracker.Entries().Count());

                Assert.Equal(EntityState.Unchanged, context.Entry(category).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(category.Products[0]).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(category.Products[0].Details).State);
                Assert.Equal(EntityState.Detached, context.Entry(category.Products[1]).State);
                Assert.Equal(EntityState.Detached, context.Entry(category.Products[1].Details).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(category.Products[2]).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(category.Products[2].Details).State);

                Assert.Same(category, category.Products[0].Category);
                Assert.Same(category, category.Products[1].Category);
                Assert.Same(category, category.Products[2].Category);

                Assert.Equal(category.Id, category.Products[0].CategoryId);
                Assert.Equal(category.Id, category.Products[1].CategoryId);
                Assert.Equal(category.Id, category.Products[2].CategoryId);

                Assert.Same(category.Products[0], category.Products[0].Details.Product);
                Assert.Null(category.Products[1].Details.Product);
                Assert.Same(category.Products[2], category.Products[2].Details.Product);
            }
        }
Пример #24
0
        public async Task SaveChangesAsync_only_passes_dirty_entries_to_Database()
        {
            var passedEntries = new List<IUpdateEntry>();
            var database = new Mock<IDatabase>();
            database.Setup(s => s.SaveChangesAsync(It.IsAny<IReadOnlyList<IUpdateEntry>>(), It.IsAny<CancellationToken>()))
                .Callback<IEnumerable<IUpdateEntry>, CancellationToken>((e, c) => passedEntries.AddRange(e))
                .Returns(Task.FromResult(3));

            var valueGenMock = new Mock<IValueGeneratorSelector>();
            valueGenMock.Setup(m => m.Select(It.IsAny<IProperty>(), It.IsAny<IEntityType>())).Returns(Mock.Of<ValueGenerator>());

            var servicesMock = new Mock<IDatabaseProviderServices>();
            servicesMock.Setup(m => m.Database).Returns(database.Object);
            servicesMock.Setup(m => m.ValueGeneratorSelector).Returns(valueGenMock.Object);
            servicesMock.Setup(m => m.ModelSource).Returns(new Mock<ModelSource>(new DbSetFinder(), new CoreConventionSetBuilder())
                { CallBase = true }.Object);
            servicesMock
                .Setup(m => m.ModelValidator)
                .Returns(new LoggingModelValidator(new Logger<LoggingModelValidator>(new LoggerFactory())));
                
            var sourceMock = new Mock<IDatabaseProvider>();
            sourceMock.Setup(m => m.IsConfigured(It.IsAny<IDbContextOptions>())).Returns(true);
            sourceMock.Setup(m => m.GetProviderServices(It.IsAny<IServiceProvider>())).Returns(servicesMock.Object);

            var services = new ServiceCollection();
            services.AddEntityFramework();
            services.AddInstance(sourceMock.Object);
            var serviceProvider = services.BuildServiceProvider();

            using (var context = new EarlyLearningCenter(serviceProvider, new DbContextOptionsBuilder().Options))
            {
                context.Entry(new Category { Id = 1 }).State = EntityState.Unchanged;
                context.Entry(new Category { Id = 2 }).State = EntityState.Modified;
                context.Entry(new Category { Id = 3 }).State = EntityState.Added;
                context.Entry(new Category { Id = 4 }).State = EntityState.Deleted;
                Assert.Equal(4, context.ChangeTracker.Entries().Count());

                await context.SaveChangesAsync();
            }

            Assert.Equal(3, passedEntries.Count);

            database.Verify(
                s => s.SaveChangesAsync(It.IsAny<IReadOnlyList<InternalEntityEntry>>(), It.IsAny<CancellationToken>()),
                Times.Once);
        }
        private static void KeyValueAttachTest(Action<Category, ChangeTracker> tracker, bool expectModified = false)
        {
            using (var context = new EarlyLearningCenter())
            {
                var category = new Category
                    {
                        Id = 77,
                        Products = new List<Product>
                            {
                                new Product { Id = 77 },
                                new Product { Id = 0 },
                                new Product { Id = 78 }
                            }
                    };

                tracker(category, context.ChangeTracker);

                Assert.Equal(4, context.ChangeTracker.Entries().Count());

                var nonAddedState = expectModified ? EntityState.Modified : EntityState.Unchanged;

                Assert.Equal(nonAddedState, context.Entry(category).State);
                Assert.Equal(nonAddedState, context.Entry(category.Products[0]).State);
                Assert.Equal(EntityState.Added, context.Entry(category.Products[1]).State);
                Assert.Equal(nonAddedState, context.Entry(category.Products[2]).State);

                Assert.Equal(77, category.Products[0].Id);
                Assert.Equal(1, category.Products[1].Id);
                Assert.Equal(78, category.Products[2].Id);

                Assert.Same(category, category.Products[0].Category);
                Assert.Same(category, category.Products[1].Category);
                Assert.Same(category, category.Products[2].Category);

                Assert.Equal(category.Id, category.Products[0].CategoryId);
                Assert.Equal(category.Id, category.Products[1].CategoryId);
                Assert.Equal(category.Id, category.Products[2].CategoryId);
            }
        }
Пример #26
0
        public void Entry_methods_delegate_to_underlying_state_manager()
        {
            var entity = new Random();
            var stateManagerMock = new Mock<IStateManager>();
            var entry = CreateInternalEntryMock().Object;
            stateManagerMock.Setup(m => m.GetOrCreateEntry(entity)).Returns(entry);

            var services = new ServiceCollection()
                .AddScoped(_ => stateManagerMock.Object);

            var serviceProvider = TestHelpers.Instance.CreateServiceProvider(services);

            using (var context = new EarlyLearningCenter(serviceProvider))
            {
                Assert.Same(entry, context.Entry(entity).GetInfrastructure());
                Assert.Same(entry, context.Entry((object)entity).GetInfrastructure());
            }
        }
        public void Can_attach_graph_using_custom_delegate()
        {
            var tracker = new MyTracker(updateExistingEntities: false);

            using (var context = new EarlyLearningCenter())
            {
                var category = new Category
                    {
                        Id = 77,
                        Products = new List<Product>
                            {
                                new Product { Id = 77 },
                                new Product { Id = 0 },
                                new Product { Id = 78 }
                            }
                    };

                context.ChangeTracker.TrackGraph(category, tracker.TrackEntity);

                Assert.Equal(4, context.ChangeTracker.Entries().Count());

                Assert.Equal(EntityState.Unchanged, context.Entry(category).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(category.Products[0]).State);
                Assert.Equal(EntityState.Added, context.Entry(category.Products[1]).State);
                Assert.Equal(EntityState.Unchanged, context.Entry(category.Products[2]).State);

                Assert.Equal(77, category.Products[0].Id);
                Assert.Equal(777, category.Products[1].Id);
                Assert.Equal(78, category.Products[2].Id);

                Assert.Same(category, category.Products[0].Category);
                Assert.Same(category, category.Products[1].Category);
                Assert.Same(category, category.Products[2].Category);

                Assert.Equal(category.Id, category.Products[0].CategoryId);
                Assert.Equal(category.Id, category.Products[1].CategoryId);
                Assert.Equal(category.Id, category.Products[2].CategoryId);
            }
        }
Пример #28
0
        private static void TrackMultipleEntitiesTestEnumerable(
            Action<DbContext, IEnumerable<object>> categoryAdder,
            Action<DbContext, IEnumerable<object>> productAdder, EntityState expectedState)
        {
            using (var context = new EarlyLearningCenter(TestHelpers.Instance.CreateServiceProvider()))
            {
                var category1 = new Category { Id = 1, Name = "Beverages" };
                var category2 = new Category { Id = 2, Name = "Foods" };
                var product1 = new Product { Id = 1, Name = "Marmite", Price = 7.99m };
                var product2 = new Product { Id = 2, Name = "Bovril", Price = 4.99m };

                categoryAdder(context, new List<Category> { category1, category2 });
                productAdder(context, new List<Product> { product1, product2 });

                Assert.Same(category1, context.Entry(category1).Entity);
                Assert.Same(category2, context.Entry(category2).Entity);
                Assert.Same(product1, context.Entry(product1).Entity);
                Assert.Same(product2, context.Entry(product2).Entity);

                Assert.Same(category1, context.Entry(category1).Entity);
                Assert.Equal(expectedState, context.Entry(category1).State);
                Assert.Same(category2, context.Entry(category2).Entity);
                Assert.Equal(expectedState, context.Entry(category2).State);

                Assert.Same(product1, context.Entry(product1).Entity);
                Assert.Equal(expectedState, context.Entry(product1).State);
                Assert.Same(product2, context.Entry(product2).Entity);
                Assert.Equal(expectedState, context.Entry(product2).State);
            }
        }
        public void Can_attach_parent_with_child_collection()
        {
            using (var context = new EarlyLearningCenter())
            {
                var category = new Category
                    {
                        Id = 1,
                        Products = new List<Product>
                            {
                                new Product { Id = 1 },
                                new Product { Id = 2 },
                                new Product { Id = 3 }
                            }
                    };

                context.ChangeTracker.TrackGraph(category, e => e.State = EntityState.Modified);

                Assert.Equal(4, context.ChangeTracker.Entries().Count());

                Assert.Equal(EntityState.Modified, context.Entry(category).State);
                Assert.Equal(EntityState.Modified, context.Entry(category.Products[0]).State);
                Assert.Equal(EntityState.Modified, context.Entry(category.Products[1]).State);
                Assert.Equal(EntityState.Modified, context.Entry(category.Products[2]).State);

                Assert.Same(category, category.Products[0].Category);
                Assert.Same(category, category.Products[1].Category);
                Assert.Same(category, category.Products[2].Category);

                Assert.Equal(category.Id, category.Products[0].CategoryId);
                Assert.Equal(category.Id, category.Products[1].CategoryId);
                Assert.Equal(category.Id, category.Products[2].CategoryId);
            }
        }
Пример #30
0
        private void ChangeStateWithMethod(Action<DbContext, object> action, EntityState initialState, EntityState expectedState)
        {
            using (var context = new EarlyLearningCenter(TestHelpers.Instance.CreateServiceProvider()))
            {
                var entity = new Category { Id = 1, Name = "Beverages" };
                var entry = context.Entry(entity);

                entry.State = initialState;

                action(context, entity);

                Assert.Equal(expectedState, entry.State);
            }
        }
        private static async Task TrackMultipleEntitiesTestEnumerable(
            Func <EarlyLearningCenter, IEnumerable <Category>, Task> categoryAdder,
            Func <EarlyLearningCenter, IEnumerable <Product>, Task> productAdder, EntityState expectedState)
        {
            using (var context = new EarlyLearningCenter())
            {
                var category1 = new Category {
                    Id = 1, Name = "Beverages"
                };
                var category2 = new Category {
                    Id = 2, Name = "Foods"
                };
                var product1 = new Product {
                    Id = 1, Name = "Marmite", Price = 7.99m
                };
                var product2 = new Product {
                    Id = 2, Name = "Bovril", Price = 4.99m
                };

                await categoryAdder(
                    context, new List <Category> {
                    category1, category2
                });
                await productAdder(
                    context, new List <Product> {
                    product1, product2
                });

                Assert.Same(category1, context.Entry(category1).Entity);
                Assert.Same(category2, context.Entry(category2).Entity);
                Assert.Same(product1, context.Entry(product1).Entity);
                Assert.Same(product2, context.Entry(product2).Entity);

                Assert.Same(category1, context.Entry(category1).Entity);
                Assert.Equal(expectedState, context.Entry(category1).State);
                Assert.Same(category2, context.Entry(category2).Entity);
                Assert.Equal(expectedState, context.Entry(category2).State);

                Assert.Same(product1, context.Entry(product1).Entity);
                Assert.Equal(expectedState, context.Entry(product1).State);
                Assert.Same(product2, context.Entry(product2).Entity);
                Assert.Equal(expectedState, context.Entry(product2).State);
            }
        }
Пример #32
0
        [Fact] // Issue #1246
        public void Can_set_set_to_Unchanged_with_inconsistent_FK_principal_first_fully_fixed_up()
        {
            using (var context = new EarlyLearningCenter(TestHelpers.Instance.CreateServiceProvider()))
            {
                var category = new Category { Id = 1, Name = "Beverages" };
                var product = new Product { Id = 1, CategoryId = 7, Name = "Marmite", Category = category };
                category.Products = new List<Product> { product };

                context.Entry(category).State = EntityState.Unchanged;

                Assert.Equal(7, product.CategoryId);
                Assert.Same(product, category.Products.Single());
                Assert.Same(category, product.Category);
                Assert.Equal(EntityState.Unchanged, context.Entry(category).State);
                Assert.Equal(EntityState.Detached, context.Entry(product).State);

                context.Entry(product).State = EntityState.Unchanged;

                Assert.Equal(7, product.CategoryId);
                Assert.Same(product, category.Products.Single());
                Assert.Same(category, product.Category);
                Assert.Equal(EntityState.Unchanged, context.Entry(category).State);

                // Dependent is Unchanged here because the FK change happened before it was attached
                Assert.Equal(EntityState.Unchanged, context.Entry(product).State);
            }
        }
Пример #33
0
        private static void TrackEntitiesTest(
            Func <DbSet <Category>, Category, EntityEntry <Category> > categoryAdder,
            Func <DbSet <Product>, Product, EntityEntry <Product> > productAdder, EntityState expectedState)
        {
            using (var context = new EarlyLearningCenter())
            {
                var category1 = new Category {
                    Id = 1, Name = "Beverages"
                };
                var category2 = new Category {
                    Id = 2, Name = "Foods"
                };
                var product1 = new Product {
                    Id = 1, Name = "Marmite", Price = 7.99m
                };
                var product2 = new Product {
                    Id = 2, Name = "Bovril", Price = 4.99m
                };

                var categoryEntry1 = categoryAdder(context.Categories, category1);
                var categoryEntry2 = categoryAdder(context.Categories, category2);
                var productEntry1  = productAdder(context.Products, product1);
                var productEntry2  = productAdder(context.Products, product2);

                Assert.Same(category1, categoryEntry1.Entity);
                Assert.Same(category2, categoryEntry2.Entity);
                Assert.Same(product1, productEntry1.Entity);
                Assert.Same(product2, productEntry2.Entity);

                Assert.Same(category1, categoryEntry1.Entity);
                Assert.Equal(expectedState, categoryEntry2.State);
                Assert.Same(category2, categoryEntry2.Entity);
                Assert.Equal(expectedState, categoryEntry2.State);

                Assert.Same(product1, productEntry1.Entity);
                Assert.Equal(expectedState, productEntry1.State);
                Assert.Same(product2, productEntry2.Entity);
                Assert.Equal(expectedState, productEntry2.State);

                Assert.Same(((IAccessor <InternalEntityEntry>)categoryEntry1).Service, ((IAccessor <InternalEntityEntry>)context.Entry(category1)).Service);
                Assert.Same(((IAccessor <InternalEntityEntry>)categoryEntry2).Service, ((IAccessor <InternalEntityEntry>)context.Entry(category2)).Service);
                Assert.Same(((IAccessor <InternalEntityEntry>)productEntry1).Service, ((IAccessor <InternalEntityEntry>)context.Entry(product1)).Service);
                Assert.Same(((IAccessor <InternalEntityEntry>)productEntry2).Service, ((IAccessor <InternalEntityEntry>)context.Entry(product2)).Service);
            }
        }