Beispiel #1
0
        public void TestDetachAllTrackedEntities(int numCollection)
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <Chapter06Context>();

            using (var context = new Chapter06Context(options))
            {
                context.Database.EnsureCreated();
                var entityToDetach = context.AddManyTopWithRelationsToDb();
                //ATTEMPT
                using (new TimeThings(_output, $"detach all tracked entities - {numCollection * 3:n0} tracked entities."))
                {
                    foreach (var entityEntry in context.ChangeTracker.Entries()) //#A
                    {
                        if (entityEntry.Entity != null)                          //#B
                        {
                            entityEntry.State = EntityState.Detached;            //#C
                        }
                    }

                    /********************************************
                     #A This will iterate through each tracked EntityEntry in the current DbContext instance
                     #B This filters out tracked entities where the entity class instance has been set to null
                     #C This sets the state of the EntityEntry to Detached
                     **********************************************/
                }

                //VERIFY
                var topEntity = context.Entry(entityToDetach);
                entityToDetach.Collection1.All(x => context.Entry(x).State == EntityState.Detached).ShouldBeTrue();
                entityToDetach.Collection2.All(x => context.Entry(x).State == EntityState.Detached).ShouldBeTrue();
                entityToDetach.Collection3.All(x => context.Entry(x).State == EntityState.Detached).ShouldBeTrue();
            }
        }
        public void TestBookQueryWithSeparateIncludes()
        {
            //SETUP
            var showlog = false;
            var options = SqliteInMemory.CreateOptionsWithLogging <Chapter06Context>(log =>
            {
                if (showlog)
                {
                    _output.WriteLine(log.Message);
                }
            });

            using (var context = new Chapter06Context(options))
            {
                context.Database.EnsureCreated();
                context.AddManyTopWithRelationsToDb();
            }
            using (var context = new Chapter06Context(options))
            {
                //ATTEMPT
                var     dummy1 = context.ManyTops.ToList();
                var     dummy2 = context.ManyTops.ToList();
                ManyTop result;
                using (new TimeThings(_output, "sync load - first time"))
                {
                    result = context.ManyTops.Single();                     //#A
                    var a = context.Set <Many1>()                           //#B
                            .Where(x => x.ManyTopId == result.Id).ToList(); //#B
                    var b = context.Set <Many2>()                           //#B
                            .Where(x => x.ManyTopId == result.Id).ToList(); //#B
                    var c = context.Set <Many3>()                           //#B
                            .Where(x => x.ManyTopId == result.Id).ToList(); //#B

                    /*********************************************************
                     #A This read in the main entity class, ManyTop that the relationships link to first
                     #B Then you read in the collections one by one. Relational fixup will fill in the navigational properties in the main entity class, ManyTop
                     **********************************************************/
                }
                using (new TimeThings(_output, "sync load - second time"))
                {
                    result = context.ManyTops.Single();
                    var loadRels = new
                    {
                        a = context.Set <Many1>().Where(x => x.ManyTopId == result.Id).ToList(),
                        b = context.Set <Many2>().Where(x => x.ManyTopId == result.Id).ToList(),
                        c = context.Set <Many3>().Where(x => x.ManyTopId == result.Id).ToList(),
                    };
                }

                //VERIFY
                result.Collection1.Count.ShouldEqual(100);
                result.Collection2.Count.ShouldEqual(100);
                result.Collection3.Count.ShouldEqual(100);
            }
        }
        public void TestBookQueryWithSeparateIncludes()
        {
            //SETUP
            var showlog = false;
            var options = SqliteInMemory.CreateOptionsWithLogging <Chapter06Context>(log =>
            {
                if (showlog)
                {
                    _output.WriteLine(log.Message);
                }
            });

            using (var context = new Chapter06Context(options))
            {
                context.Database.EnsureCreated();
                context.AddManyTopWithRelationsToDb();
            }
            using (var context = new Chapter06Context(options))
            {
                //ATTEMPT
                var     dummy1 = context.ManyTops.ToList();
                var     dummy2 = context.ManyTops.ToList();
                ManyTop result;
                var     id = 1;
                using (new TimeThings(_output, "sync load - first time"))
                {
                    result = context.ManyTops
                             .AsSplitQuery() //#A
                             .Include(x => x.Collection1)
                             .Include(x => x.Collection2)
                             .Include(x => x.Collection3)
                             .Single(x => x.Id == id);

                    /*********************************************************
                     #A This will cause each Include to be loaded separately, thus stopping the multiplication problem
                     **********************************************************/
                }
                using (new TimeThings(_output, "sync load - second time"))
                {
                    result = context.ManyTops
                             .AsSplitQuery()
                             .Include(x => x.Collection1)
                             .Include(x => x.Collection2)
                             .Include(x => x.Collection3)
                             .Single();
                }

                //VERIFY
                result.Collection1.Count.ShouldEqual(100);
                result.Collection2.Count.ShouldEqual(100);
                result.Collection3.Count.ShouldEqual(100);
            }
        }
        public async Task TestBookQueryWithSeparateIncludesAsync()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <Chapter06Context>();

            using (var context = new Chapter06Context(options))
            {
                context.Database.EnsureCreated();
                context.AddManyTopWithRelationsToDb();
            }
            using (var context = new Chapter06Context(options))
            {
                //ATTEMPT
                var     dummy1 = context.ManyTops.ToList();
                var     dummy2 = context.ManyTops.ToList();
                ManyTop result;
                using (new TimeThings(_output, "async load - first time"))
                {
                    result = await context.ManyTops
                             .AsSplitQuery()
                             .Include(x => x.Collection1)
                             .Include(x => x.Collection2)
                             .Include(x => x.Collection3)
                             .SingleAsync();

                    /*********************************************************
                     #A This read in the main entity class, ManyTop that the relationships link to first
                     #B Then you read in the collections one by one. Relational fixup will fill in the navigational properties in the main entity class, ManyTop
                     **********************************************************/
                }
                using (new TimeThings(_output, "async load - second time"))
                {
                    result = await context.ManyTops
                             .AsSplitQuery()
                             .Include(x => x.Collection1)
                             .Include(x => x.Collection2)
                             .Include(x => x.Collection3)
                             .SingleAsync();
                }

                //VERIFY
                result.Collection1.Count.ShouldEqual(100);
                result.Collection2.Count.ShouldEqual(100);
                result.Collection3.Count.ShouldEqual(100);
            }
        }
        public void TestDetachAllTrackedEntities(int numCollection)
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <Chapter06Context>();

            using (var context = new Chapter06Context(options))
            {
                context.Database.EnsureCreated();
                var entityToDetach = context.AddManyTopWithRelationsToDb();
                //ATTEMPT
                using (new TimeThings(_output, $"detach all tracked entities - {numCollection * 3:n0} tracked entities."))
                {
                    context.ChangeTracker.Clear();
                }

                //VERIFY
                var topEntity = context.Entry(entityToDetach);
                entityToDetach.Collection1.All(x => context.Entry(x).State == EntityState.Detached).ShouldBeTrue();
                entityToDetach.Collection2.All(x => context.Entry(x).State == EntityState.Detached).ShouldBeTrue();
                entityToDetach.Collection3.All(x => context.Entry(x).State == EntityState.Detached).ShouldBeTrue();
            }
        }
        public void TestDetachViaCreatingNewDbContext(int numCollection)
        {
            //SETUP
            ManyTop entityToDetach;
            var     options = SqliteInMemory.CreateOptions <Chapter06Context>();

            using (var context = new Chapter06Context(options))
            {
                context.Database.EnsureCreated();
                entityToDetach = context.AddManyTopWithRelationsToDb(numCollection);
            }
            //ATTEMPT
            using (new TimeThings(_output, $"detach by creating new DbContext - {numCollection * 3:n0} tracked entities."))
            {
                using (var context = new Chapter06Context(options))
                {
                    context.Database.EnsureCreated();
                }
            }

            //VERIFY
        }
        public void TestBookQueryWithNormalIncludes()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <Chapter06Context>();

            using (var context = new Chapter06Context(options))
            {
                context.Database.EnsureCreated();
                context.AddManyTopWithRelationsToDb();
            }
            using (var context = new Chapter06Context(options))
            {
                //ATTEMPT
                var     dummy1 = context.ManyTops.ToList();
                var     dummy2 = context.ManyTops.ToList();
                ManyTop result;
                using (new TimeThings(_output, "normal includes - first time"))
                {
                    result = context.ManyTops
                             .Include(x => x.Collection1)
                             .Include(x => x.Collection2)
                             .Include(x => x.Collection3)
                             .Single();
                }
                using (new TimeThings(_output, "normal includes - second time"))
                {
                    result = context.ManyTops
                             .Include(x => x.Collection1)
                             .Include(x => x.Collection2)
                             .Include(x => x.Collection3)
                             .Single();
                }

                //VERIFY
                result.Collection1.Count.ShouldEqual(100);
                result.Collection2.Count.ShouldEqual(100);
                result.Collection3.Count.ShouldEqual(100);
            }
        }
        public void TestCostOfNotDetaching(int numCollection)
        {
            //SETUP
            ManyTop entityToDetach;
            var     options = SqliteInMemory.CreateOptions <Chapter06Context>();

            using (var context = new Chapter06Context(options))
            {
                context.Database.EnsureCreated();

                //ATTEMPT
                using (new TimeThings(_output, "SaveChanges - no tracked entities."))
                {
                    context.SaveChanges();
                }
                using (new TimeThings(_output, "SaveChanges - no tracked entities."))
                {
                    context.SaveChanges();
                }

                entityToDetach = context.AddManyTopWithRelationsToDb(numCollection);
                var numEntities = entityToDetach.Collection1.Count +
                                  entityToDetach.Collection2.Count +
                                  entityToDetach.Collection3.Count;


                using (new TimeThings(_output, $"SaveChanges - {numEntities:n0} tracked entities."))
                {
                    context.SaveChanges();
                }
                using (new TimeThings(_output, $"SaveChanges - {numEntities:n0} tracked entities."))
                {
                    context.SaveChanges();
                }
            }

            //VERIFY
        }
Beispiel #9
0
        public void ExampleDetachViaCreatingNewDbContext()
        {
            //SETUP

            var options = SqliteInMemory.CreateOptions <Chapter06Context>();

            options.StopNextDispose();
            using (var context = new Chapter06Context(options))
            {
                context.Database.EnsureCreated();
                context.AddManyTopWithRelationsToDb();
            }

            //ATTEMPT
            ManyTop entityToDetach;                                   //#A

            using (var tempContext = new Chapter06Context(options))   //#B
            {
                entityToDetach = tempContext.ManyTops.Single();       //#C
                var a = tempContext.Set <Many1>()                     //#D
                        .Where(x => x.ManyTopId == entityToDetach.Id) //#D
                        .ToList();                                    //#D
                //... rest of loads left out to shorten the example
            }                                                         //#E
            //… further code that uses the entityToDetach variable  //#F

            /************************************************************************
             #A This is the variable which will hold the detached entity class with its relationships that were read in separately
             #B Create a new instance of the application's DbContext. This must be done manually because you should not dispose of an instance that has been created by dependency injections
             #C Read of the top level entity class
             #D Read of the Many1 instances. Relational fixup will fill in the navigational collection in the ManyTop class which holds the loaded Many1 instances
             #E The closing of the using block means that the tempContext is disposed, including all ist tracking data
             #F As this point all the entity class instances read in while in the using block are detached from any DbContext
             * ********************************/

            //VERIFY
            entityToDetach.Collection1.Count.ShouldEqual(100);
        }