0

I'm using MVC5 with EF Core 2.2 and DI. I have the DbContext setup as Scoped but appears it's acting like a singlton.

Request 1: Creates a Transaction Scope. Creates a new object1 in DbContext and adds it, Creates a new object2 adds it but fails and transaction rollsback.

Request 2: Creates a Transaction Scope. Creates new object1 in DbContext but fails due to it already tracking changes from Request 1. It's not in the DB. Restarting web application allows the first request to go through again (because tracker is clear)

I have no idea how it is still tracking that object if the second request should have been a completely new context, and have nothing in tracking. If I don't use DI and just instantiate the context in the controller, it works.

Error: The instance of entity type cannot be tracked because another instance of this type with the same key is already being tracked

services.AddDbContext<ApplicationDbContext>(options =>
{
            options.UseSqlServer(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString, builder =>
            {
                builder.UseRowNumberForPaging();
            });
}, ServiceLifetime.Scoped);

services.AddScoped(typeof(ChairManager));

ChairController with DI of Manager class

public ChairController(ChairManager chairManager, IServiceProvider services)...

ChairManager class with DI of Context

public ChairManager(ApplicationDbContext context)...

ChairController calling ChairManager method

await _chairManager.AddChairAsync(chair)

Now if I do something like this, and don't use DI. No issues at all...

public ChairController(IServiceProvider services)
{
        var context = ApplicationDbContext.Create();
        _chairManager = new ChairManager2(context);
}

...

await _chairManager.AddChairAsync(chair)
Clarke76
  • 724
  • 1
  • 7
  • 17
  • Can you provide a code sample for how `AddChairAsync` is implemented, and the exact error message? – rhytonix Feb 12 '20 at 12:09
  • I updated the post with the error, but I also figured out the issue. I was partially correct. The scoped context was not being disposed. – Clarke76 Feb 12 '20 at 14:13

1 Answers1

0

So the issue was the context wasn't being disposed, so it was acting like a singleton. After some searching around I found these two answers that fixed the problem.

For the main controllers I used this. The key here was the class "ServiceScopeModule". That handled the disposing of scoped resources.

For Web API controllers I implemented the answer from here. Specifically the "MsDiHttpControllerActivator" class.

I now get a properly scoped DbContext in MVC 5 that disposes after the end request.

Clarke76
  • 724
  • 1
  • 7
  • 17