I started off trying to expand my sample from last week’s post and hit some issues when trying to add a migration for a new DbContext.
The Setup
I added the following DbContext that only has one DbSet and auto applies migrations in the constructor.
using EfSqlite.Models; using Microsoft.EntityFrameworkCore; public sealed class ContactsDbContext : DbContext { private static bool _created; public DbSet<Contact> Contacts { get; set; } public ContactsDbContext(DbContextOptions<ContactsDbContext> options) : base(options) { if (_created) return; Database.Migrate(); _created = true; } }
The command
Using Visual Studio’s Package Manager Console I ran the following command.
Add-Migration AddContacts -Context ContactsDbContext
Error 1 – No parameterless constructor
The above command resulted in the following error.
No parameterless constructor was found on ‘ContactsDbContext’. Either add a parameterless constructor to ‘ContactsDbContext’ or add an implementation of ‘IDbContextFactory<ContactsDbContext>’ in the same assembly as ‘ContactsDbContext’.
I read the first sentence and added a parameterless constructor to ContactsDbContext. I did think it was strange that a parameterless constructor wasn’t required the other contexts I had written in the past, but the error said to add a parameterless constructor so that is what I did.
Error 2 – System.InvalidOperationException: No database provider has been configured for this DbContext
Now having a parameterless constructor I ran the Add-Migration command again and was greeted with the following error.
System.InvalidOperationException: No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext.
The second error forced me to step back and think more about what the problem was as it didn’t have an action I could take as the first sentence, which is, of course, my fault for not fully digesting what the error was saying.
The fix
The bit I was missing was the fact that I hadn’t added the following to the ConfigureServices function of the project’s Startup class.
services.AddDbContext<ContactsDbContext>(options => options.UseSqlite(Configuration.GetConnectionString("Sqlite")));
With the above added I removed the parameterless constructor from ContactsDbContext and was able to successfully run the add migration command again.
Wrapping up
The moral of the story is to actually read the full error message before running off and trying to fix the problem. The second error message saying “using AddDbContext on the application service provider” is what triggered me to head in the right direction.
This was also a good reminder that tools like the ones used by Add-Migration can/do compile the project they are being used on in order to have enough context to perform their tasks.
I had this exact same problem / error when using a .NET Core 1.1 project that I ‘updated’ to .NET Core 2.0 by setting the “Target Framework” in the project properties.
Your solution didn’t solve the issue in my case.
Creating a .NET Core 2.0 from scratch using the Visual Studio 2017 new project wizard did not throw the errors mentioned above.
Glad to hear you got a working solution. Thank you for sharing!
I stumbled across this post while searching for examples of running migrations elsewhere than app startup. Most examples run migrations in Startup.Configure, but this causes app startup to fail if the database is unavailable. We’re developing a service where the database isn’t essential for all operations so I still want the service to initialize if the db is down, and to “lazy-migrate” on demand. It feels like running migrations in the DbContext constructor ought to be more common.
Probably someone will jump in with 1000 reasons why this is a bad idea but I was happy to see this either way.
Glad to hear it was helpful.