I’ve been getting the error “The underlying provider failed on Open.” recently and I’ve been pulling my hair out trying to figure out why. On closer inspection of the error the inner exception is “The connection was not closed. The connection’s current state is connecting.” and the stack trace is
"at System.Data.ProviderBase.DbConnectionClosedConnecting.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.Open()
at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)"
As far as I can tell the error seems to happen at random or possibly when making changes to the application. Any help would be greatly appreciated.
My current setup is
- IIS Express
- Microsoft SQL Server Express Edition
- Visual Studio 2012
- MVC Web API \ Asp.net MVC 4
- Entity Framework 5
My data layer is modeled off the Repository pattern and injected via Structure map.
Repository
public class Repository<T> : IDisposable, IRepository<T> where T : class
{
private readonly DbSet<T> _dbSet;
private readonly DbContext _dbContext;
public Repository(IDbContextFactory<MyContext> dbContextFactory)
{
_dbContext = dbContextFactory.Create();
_dbSet = _dbContext.Set<T>();
}
//removed for brevitity
public void Dispose()
{
_dbContext.Dispose();
}
DbContextFactory
public class MyContextFactor : IDbContextFactory<MyContext>, IDisposable
{
private MyContext _dataContext;
public MyContextFactor Create()
{
return _dataContext ?? (_dataContext = new MyContext());
}
public void Dispose()
{
_dataContext.Dispose();
}
}
Structure Map Registry for IOC
For(typeof(IDbContextFactory<MyContext>)).HybridHttpOrThreadLocalScoped().Use(typeof(MyContextFactory));
Connection String
<add name="MyContextConnectionString" connectionString="metadata=res://*/Model.MyProject.csdl|res://*/Model.MyProject.ssdl|res://*/Model.MyProject.msl;provider=System.Data.SqlClient;provider connection string="data source=(local);initial catalog=MyDB;User Id=SQLUser;Password=****;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient"/>
Things I’ve attempted to fix the problem and so far haven’t worked
- ensure context is per http context via structure map scope
- added dispose to repository
- added dispose to ContextFactory
- switched from Intergrated Sql auth to Sql authentication
This turned out to be an ActionFilterAttribute that was being cached. The ActionFilterAttribute had a Entity framework context that wasn’t being disposed of correctly and was being shared across requests.