Working with EF Core Migrations

How to create migrations in EF Core with SQL Server provider? How to handle migrations with EF Core? Migrations in a different library than your main project? These are questions we will try to respond in this article

After a few years working with other ORMs it was about time to come back to Entity Framework to see how it evolved.

The last time I worked with it, it had the .edmx designer. It was fun sometimes, but I remember having projects with huge databases that were a mess when you needed to update something.

Back then, we didn’t know about tools like Flyway or DbUp . Versioning database scripts or integrating them into the pipelines wasn't considered. We just used tools to sync everything in place: schema and data.

Entity Framework Code first approach #

The code-first approach is one of the most common scenarios when talking about databases and .NET Core projects. When using this approach, you consider your C# code to be the source of truth. You extend the DbContext class and after that, you make the changes in the entity classes.

To be fair, I don't rely on migrations done from the codebase. I advise you to take control and generate idempotent SQL scripts from these migrations.

Adding an EF Core migration #

We assume we already have a project and we want to add a change in one of the Entities, and we need to add a migration.
Assuming that you are using the CLI and you have an application with only one project and you are in the root folder hierarchy you will use something like this

dotnet ef migrations add {migrationName} --project {projectName}

Keep in mind that when running a command, you can also use paths. These are relative to the folder you are running them from the CLI. Usually the root of the project, the one with the .sln file.

dotnet ef migrations add {migrationName} --output-dir {../MyApp.Domain/Migrations} --project {projectName}

Adding an EF Core migration in a different project than your main one? #

Real-life applications are usually split into different projects. We usually want to keep the domain objects separate from the web application. You will have multiple ‘whatever’ layers that will make the separation clearer for the teams.

Make sure you navigate to your MyApp.Domain CLI and run the commands from there

dotnet ef migrations add MyMigration --output-dir ../MyApp.Domain/Migrations --startup-project ../MyApp.Web --verbose

Otherwise, you will end up with a big error like the one below.

Y_our target project 'MyApp.Web' doesn't match your migrations assembly 'MyApp.Domain'. Either change your target project or change your migrations assembly.
Change your migrations assembly by using DbContextOptionsBuilder. E.g. options.UseSqlServer(connection, b => b.MigrationsAssembly("MyApp.Web")). By default, the migrations assembly is the assembly containing the DbContext.
Change your target project to the migrations project by using the Package Manager Console's Default project drop-down list, or by executing "dotnet ef" from the directory containing the migrations project._

To fix that, you will need to specify in Startup.cs the assembly for the migrations.

services.AddDbContext<TechEventContext\>(options \=>
  {
      options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
          m \=> m.MigrationsAssembly("MyApp.Domain"));
  });

Once you did this, you need to run the command again. If successful, you will have the new migration file added to your MyApp.Domain project, under the Migrations folder.