efcore: An attempt was made to use the context while it is being configured. A DbContext instance cannot be used inside OnConfiguring since it is still being configured at this point.

I am trying to use DI for my dbContext with MVC6/EF7 RC1.

I am instantiating my ContextTest (inherited from dbcontext) using [FromServices] attribute in the constructor of my TestService class

Sample code:

[FromServices]
public ContextTest  _testContext { get; set; }

public TestService(ContextTest  testContext)
{
_testContext  = testContext;
}

public async GetData()
{
await _testContext.GetFunA();
await _testContext.GetFunB();
await _testContext.GetFunC();
}

Startup.cs

 services.AddEntityFramework()
                .AddSqlServer()
                .AddDbContext<ContextTest  >(options => options.UseSqlServer(connection))

Exception:

Sporadically i am running into below exception

“An attempt was made to use the context while it is being configured. A DbContext instance cannot be used inside OnConfiguring since it is still being configured at this point.”

My 2 cents: Something to with Async calls (DI injects only 1 instance and i am trying to fire 3 queries in parallel.

Any suggestions?

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 2
  • Comments: 19 (8 by maintainers)

Most upvoted comments

@valcs007 you are using DbContext in TestService, which is possibly singleton and you end up using the one and only DbContext in your whole app. I’ve ran into same problem due to inaccurate design of my services: controller used some service injected through constructor to actually perform business logic, while this service was a singleton with DbContext injected through constructor again. So I ended up trying to operate on the same DbContext in every request. When there were few requests, it worked fine, but under some pressure bunch of exceptions begin to occur like

Invalid operation. The connection is closed.
An attempt was made to use the context while it is being configured. A DbContext instance cannot be used inside OnConfiguring since it is still being configured at this point.
There is already an open DataReader associated with this Command which must be closed first.
The connection was not closed. The connection's current state is connecting.
The context cannot be viewed while the model is being created

Be careful and pay attention to register all of your services with correct DI lifetime management. Do not inject Scoped and Transient services into singletons. P.S. I hope my comment will someday help someone 😃

@durilka DbContext is not thread safe. It is never safe to have the same instance being accessed in parallel.

Had the same problem. In my case I added a claims transformer implementation using

        services.AddSingleton<IClaimsTransformation, ClaimsTransformer>();

since that class used a UserManager instance which used a dbcontext instance it threw this error. after switching to

        services.AddTransient<IClaimsTransformation, ClaimsTransformer>();

the problem seems to be fixed

[Fact]
public void Context_cannot_be_used_in_OnConfiguring()
{
    var serviceProvider = new ServiceCollection()
        .AddEntityFrameworkInMemoryDatabase()
        .BuildServiceProvider();

    using (var context = new UseInOnConfiguringContext(serviceProvider))
    {
        Assert.Equal(
            CoreStrings.RecursiveOnConfiguring,
            Assert.Throws<InvalidOperationException>(() => context.Products.ToList()).Message);
    }
}

private class UseInOnConfiguringContext : DbContext
{
    private readonly IServiceProvider _serviceProvider;

    public UseInOnConfiguringContext(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public DbSet<Product> Products { get; set; }

    protected internal override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseInternalServiceProvider(_serviceProvider);

        Products.ToList();

        base.OnConfiguring(optionsBuilder);
    }
}

I’d like to reopen this. This can happen if for instance the web api controller has two methods (or same method in parallel) that are invoked in parallel using the same DbContext. Since the DbContext is lazily initialized, it will happen only when a user attempts a query, bringing a race condition with the exception in question.

So, imo, the DbContext::InitializeServices (or even DbContext::InternalServiceProvider::get) should be properly locked for the same instance and not throwing the exception. The second call should be simply blocked until the first finishes initialisation.

Here’s a trace of what happens in my case:

System.InvalidOperationException: An attempt was made to use the context while it is being configured. A DbContext instance cannot be used inside OnConfiguring since it is still being configured at this point. at Microsoft.Data.Entity.DbContext.InitializeServices (IServiceProvider serviceProvider, Microsoft.Data.Entity.Infrastructure.DbContextOptions options) <0x6956ae0 + 0x001d3> in <filename unknown>:0 at Microsoft.Data.Entity.DbContext+<>c__DisplayClass12_0.<Initialize>b__0 () <0x6956a80 + 0x00023> in <filename unknown>:0 at Microsoft.Data.Entity.Internal.LazyRef1[T].get_Value () <0x69566e0 + 0x00025> in <filename unknown>:0 at Microsoft.Data.Entity.DbContext.get_ServiceProvider () <0x69569a8 + 0x00023> in <filename unknown>:0 at Microsoft.Data.Entity.DbContext.Microsoft.Data.Entity.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance () <0x6956968 + 0x00013> in <filename unknown>:0 at Microsoft.Data.Entity.Infrastructure.AccessorExtensions.GetService[TService] (IInfrastructure1 accessor) <0x6956880 + 0x00030> in <filename unknown>:0 at Microsoft.Data.Entity.Internal.InternalDbSet1[TEntity].<.ctor>b__2_0 () <0x69567b0 + 0x0001b> in <filename unknown>:0 at Microsoft.Data.Entity.Internal.LazyRef1[T].get_Value () <0x69566e0 + 0x00025> in <filename unknown>:0 at Microsoft.Data.Entity.Internal.InternalDbSet1[TEntity].System.Linq.IQueryable.get_Provider () <0x6956678 + 0x00017> in <filename unknown>:0 at System.Linq.Queryable.Any[TSource] (IQueryable1 source, System.Linq.Expressions.Expression1 predicate) <0x69562a8 + 0x0002d> in <filename unknown>:0 at Max.Logic.Reference.Validator+<>c__DisplayClass2_0.<ValidateHtNumber>b__0 () <0x6955280 + 0x0013f> in <filename unknown>:0 at System.Threading.Tasks.Task1[TResult].InnerInvoke () <0x1b81b80 + 0x00051> 24115 in <filename unknown>:0 at System.Threading.Tasks.Task.Execute () <0x1935780 + 0x0004d> in <filename unknown>:0

My last rfc in this topic. I promise.

  • The context is lazily configured on first access to the db context.
  • First access to the context happens when the user attempts to access data.
  • Accessing data, implies a query.
  • Consequently, the context is being configured when the user performs first query.
  • This is a blocking operation, operation cannot be completed until the context is created. (This is the only place where a call to DbContext can return before the initialisation ends.)
  • Given the DbContext must be operated within same thread, no other query can start until the first is complete.

Q.E.D. the exception can only be thrown if the same context is used from different thread.