Efcore: EF Core In Memory not Refreshing Data when a Record is Updated

Created on 14 Nov 2018  路  3Comments  路  Source: dotnet/efcore

See here for my simple test case:

https://github.com/aherrick/TestServerInMemoryEFCoreSelenium

I am using XUnit + Selenium to run tests. My scenario is as follows:

  1. In the Test I add a User to my In Memory DB Context.
  2. Run Selenium and Navigate to the Page. Call the Action Method on my Controller to pull that record and update it.
  3. At the end of the Test, pull the record back out and ensure it's update.

The part where this is failing is Step 3. The record is still the old original data from Step 1.

Is this a limitation of EF Core In Memory? Is something else at play here?

Thanks!

Test Code:

        [Fact]
        public void Run()
        {
            // add new user
            var db = Server.HostWeb.Services.GetService<ApplicationDbContext>();

            db.User.Add(new User()
            {
                Name = "Andrew"
            });

            db.SaveChanges();

            // edit the user from the test (Home/Edit) action
            Browser.Navigate().GoToUrl(Server.RootUrl);

            var editBtn = By.Id("edit");
            Browser.FindElement(editBtn).Click();

            // just wait until ajax is done for now.
            Thread.Sleep(20000);

            db = Server.HostWeb.Services.GetService<ApplicationDbContext>();

            // Name should be "Herrick" as my Home/Edit updates the record
            var data = db.User.First();
            Assert.Equal("Herrick", data.Name);
        }
closed-question customer-reported

Most helpful comment

@aherrick Really depends what you are trying to test. A no-tracking query for the assertion would also work in this case. But probably creating an explicit unit-of-work, for example using a scope, for the insert is a good idea anyway.

All 3 comments

@aherrick It's because the same context instance is being used both for the insertion and the assertion. This means that when you query for the entity with db.User.First() you get back the already tracked instance, which still has the old name.

@ajcvickers Thanks for the response! Is this suggestion to create a new instance via scope?

Example:

            var serviceScopeFactory = Server.HostWeb.Services.GetService<IServiceScopeFactory>();
            db = serviceScopeFactory.CreateScope().ServiceProvider.GetService<ApplicationDbContext>();

Do this does pull the correct data.

@aherrick Really depends what you are trying to test. A no-tracking query for the assertion would also work in this case. But probably creating an explicit unit-of-work, for example using a scope, for the insert is a good idea anyway.

Was this page helpful?
0 / 5 - 0 ratings