I've just started work on an experimental project using ASP.net 5, MVC6 and Entity Framework 7. I have ASP.Net Identity working fine, but then tried to add some of my own data to the DbContext and hit this problem. EF7 reports:
An unhandled exception occurred while processing the request.
InvalidOperationException: No database providers are configured. Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services.
Microsoft.Data.Entity.Internal.DatabaseProviderSelector.SelectServices(ServiceProviderSource providerSource) Stack Query Cookies Headers
InvalidOperationException: No database providers are configured. Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services.
Here's my configuration method:
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
services.AddTransient<ApplicationUnitOfWork>(instance => new ApplicationUnitOfWork());
}
ApplicationUnitOfWork
is a façade over EF7 to reduce tight coupling. Here's the whole thing so far:
public class ApplicationUnitOfWork : IUnitOfWork
{
readonly ApplicationDbContext dbContext;
public ApplicationUnitOfWork()
{
dbContext = new ApplicationDbContext();
Products = new ProductRepository(dbContext);
}
public void Dispose() { dbContext.Dispose(); }
public IUserRepository Users { get; }
public IRepository<SoftwareProduct> Products { get; }
public async Task CommitAsync() { await dbContext.SaveChangesAsync(); }
public void Cancel() { throw new NotImplementedException(); }
}
Now when I run the web application, I am able to register a user account and log in and EF creates the database, creates the Identity tables and populates them with user data. The products table is also created - so clearly at some level EF is able to use the ApplicationDbContext
and find a provider which it uses to create the database and schema.
However when I try to access my Products controller, which uses the ProductsRepository
, EF complains - even though ApplicationDbContext
is used in both cases and was used to create the database!
So how come? What's special about ASP.net Identity that it can somehow obtain a provider, but my own code can't? What "magic incantation" am I missing?