EF Core Migrations

In this tutorial, we look at what is ef core migrations are and how to create migrations. We will build an ef core migrations example app to show you how to create migrations. The app will create two models. We then use the add-migration command to create the migration. We can revert or remove the migration using the remove-migration. Once we create the migration we can push it to the database using the update-database command. Or we can also create the SQL script using the script-migration Once we have the script we can use it to update the production database. We also show you how to revert the migration from the database.

Source Code:
The source code of this project available in GitHub.

What is EF Core Migrations

In EF core we create or update data models in our code. We call this approach the Code First approach. As our app grows, we are going to make a lot of changes to our model. This will result in our database going out of sync with the model.

Hence we need to update the database as we make changes to the model. But making changes manually is error-prone. We can also create a fresh database from the model, but it will result in loss of data.

The EF Core migrations make it easier to push the changes to the database and also preserve the existing data in the database. It provides commands like add-migration, remove-migration to create & remove migrations. Once migrations are generated, we update the database using the update-database. We can also generate the migration script and execute it in the production server.

How to Create Ef Core Migrations

Let us create a new console application to see how migrations work in entity framework core. You can refer to the Tutorial Entity Framework Core Console Application to learn how to create the Console application.

First, We will create a model and context class. Then we use the Migrations commands to create migrations and then later update the database.

Create a New Console Application

Open Visual Studio 2017 and create a new .NET Core Console Application. Name the App as EFCoreMigration. You can also use the Visual Studio 2019

Install the Microsof.Entity FrameworkCore.SqlServer package, which in turn installs the Entity Framework Core package

Models for Migration

Create the Models folder and create two class Product.cs and Vendor.cs as shown below

Context

Under the models folder create the context class EFContext, which inherits from DBContext as shown below

The connection strings are hardcoded in this example for simplicity. In real-life applications, you should use the entity framework core connection string.

Preparing for Migration

There are two ways by which you can perform migrations

  • From Package Manager Console of Visual Studio
  • Using Command-line tools dotnet.exe

From Package Manager Console

To use the Package Manager Console, you need to install the Entity Framework Core Tools. Open the Package Manager and run the following command.

Installing the above package also installs the Microsoft.EntityFrameworkCore.Design package. This package actually contains the commands like add migrations, Update database, scaffold an existing database by reverse-engineering the schema of a database, etc

In ASP.NET Core 2.1 and above Visual Studio 2017 or Visual Studio 2019 automatically includes the above packages.

Using Command Line Tools

The Command line tools run from the command line and do not require the Visual Studio. If you are not using Visual Studio, then using the command line tools is the only option available to you.

.NET Core SDK version 2.1.300 and newer

If you are using the .NET Core SDK version 2.1.300 or newer you do not have to do anything. The tools have become part of the SDK. You can download the SDK from the link

Previous Versions

To Tools to work correctly, you need to install the Microsoft.EntityFrameworkCore.Design package. Go to to the solution directory and run the following command

Once you installed them, you can continue with the migration

List of Migration Commands

PMC CommandCLI CommandsRemarks
Add-Migration
dotnet ef migrations add
Adds a new migration.
Drop-Database
dotnet ef database dropDrops the database
Get-DbContextdotnet ef dbcontext infoGets information about a DbContext type.
Remove-Migration
dotnet ef migrations removeRemoves the last migration
Scaffold-DbContext
dotnet ef dbcontext scaffoldScaffolds a DbContext and entity types for a database.
Script-Migrationdotnet ef migrations scriptGenerates a SQL script from migrations.
Update-Database
dotnet ef database update
Updates the database
NAdotnet ef dbcontext list
Lists available DbContext types.
NAdotnet ef migrations listLists available migrations.

add migration

Whenever you create or Modify the domain classes, then the first thing you need to do is to create a Migration. This is done by add-migration command (or by using dotnet ef migrations add command line)

Open the Package Console manager and run the command

Where initial is the name of the migration

Add-Migration in EF Core Migrations

If the context is not part of your startup project, then for the migration to work correctly

  • You must install Microsoft.EntityFrameworkCore.Tools in the startup project
  • The reference to the project containing the context must present in the startup project
  • The Solution must compile without any errors
  • You must select the Project containing the context as the default Project in the package manager console

Common Errors

The two common errors that you may face while running the add-migration are

The term 'add-migration' is not recognized as the name of a cmdlet, function, script file, or operable program.

Solution: install the Microsoft.EntityFrameworkCore.Tools

add-migration : Build failed.

Solution: Rebuild the entire solution and correct any errors. The migration will not run if there is an error in the solution.

your target project doesn't match your migrations assembly

Solution: This error arises when you have a separate project for the context class. In such cases ensure that you set the project containing the context as default project in PMC.

Inspecting the Migration scripts

The add-migration command created three classes under the folder Migrations. One is the Migration class and the second one is the designer class & the last one is snapshot class.

Inspecting the Migration in EF Core

The Migration class

The Migration class file is named as <TimeStamp >_<MigrationName>.cs and the class name is the same as the Migration name.

It is a partial class and inherits from the Migration base class

This class has two methods. The Up() & the down()

The up method has the operations that will apply the current migrations to the database so that the database becomes in sync with this migration

The down method undo whatever the Up method so that the current migration is removed and database reverts to its previous state

The Designer class

The Designer class file named as <TimeStamp >_<MigrationName>.Designer.cs and the class name is the same as the Migration Name.

This class has one method BuildTargetModel(), which uses an instance of ModelBuilder and contains the state of the model expressed using the Fluent API

Snapshot class

The snapshot class file is named as ModelSnapshot.cs and the context name is used as the class name. It contains the latest state of the model expressed using the Fluent API.

The add-migration command generates this file when it is run for the first time. In the subsequent runs, it uses it to find out the changes to be made to the model. It then overwrites it so that it remains up to date.

Update database

The add-migration creates the migration package but does not create the database.

The update-database command is used to bring the database in sync with the latest migration or the migration name specified as the argument

Run the update-database as shown in the image above.

update-database in EF Core

Open the SQL Server and you will see that the tables Products & vendors are created in the Database. Also, note that the _EFMigrationsHistory table.

database created in EF Core

__EFMigrationsHistory

This table keeps track of the Migrations applied to the database. It contains two columns one is MigrationId and ProductVersion. MigrationId contains the Unique ID of the migration and ProductVersion is the version number of Entity Framework used.

The update-database checks if the database exists. If the table __EFMigrationsHistory does not exists then the update-database applies the migration from the beginning and then creates the __EFMigrationsHistory

If __EFMigrationsHistory already exists, then update-database checks the to see the last migration applied and then continues to apply the migrations from the last migrations to the latest. It then inserts latest migration id in the __EFMigrationsHistory table

Update-database never checks the database schema to verify whether it matches with the model. So if you accidentally delete the __EFMigrationsHistory table, alter or delete any other table or fields, the EF Core never reports an error. The error occurs only when the App is running and you query the altered/deleted table

Connection string for update-database

The update-database requires us to create the OnConfiguring() method in the context class and expects us to pass the correct connection string to the desired database provider. For example if you are using the Sql Server then you need to call the method UseSqlServer(ConnectionString)

That is because the update-database instantiates the Context class and executes the onConfiguring method so as to configure the context. It is unaware of how and where you have stored the connection string. And it does not have the access to Dependency injection container as it runs outside the project.

There are many ways you can handle this scenario. One of the ways is to read the configuration file in the OnConfiguring method as shown below

And also remember to select the select the appsettings.json and right click to select the properties. Select the property “Copy to output directory” and change the value “copy always” or “copy if newer”

Add Migration again

Let us add Rate field to the Product model.

Now, run add-migration again. Let us give the name V1 to the migration

The command now creates new migration & designer classes. But it overwrites the snapshot class.

Here is the migration class with up & down method. You can clearly see that up method has an AddColumn method and down method has DropColumn method

Now, run the update-database to update the database again with the new migrations.

Open the database and verify that the rate column appears in the Product table. Check the __EFMigrationsHistory table. You will find a new record with the new MigrationId.

Remove Migration

You can remove the migration by using the remove-migration command. The remove-migration command removes the last migration applied.

If the migrations are already applied to the database, then you will get the following error message

“The migration ‘20180927070534_V1’ has already been applied to the database. Revert it and try again. If the migration has been applied to other databases, consider reverting its changes using a new migration.”

In such a scenario, we first need to revert database update to one prior to the V1 i.e. Initial in our case.

Revert Migration

To revert a migration run the update-database with the name of the migration, to where you want to revert back.

For Example, we have created two migration initial & V1. To remove the V1 migration means, we are reverting back to Initial. Hence run the following command

Now, you can remove the migration V1 by using the command

This will remove the migrate & designer file generated and reverts the snapshot file

run update-database 0 to remove all updations applied to the database. It empties all the tables except __EFMigrationsHistory table

Script Migration

Most of the time it is not possible to use the update-database command as you may not have access to the production server. In such cases, we can generate SQL script and execute it manually on the production server.

To Create SQL script, we make use of the script-migration command.

The following is the sample script from the script-migration command. The advantageous here is you can inspect the script and may insert additional checks & queries and distribute it to the production server

The script migration does not have access to the database. It does not stop you from applying the migration again. Or apply an old migration. Hence we need to take care of that issue. To ensure that it does not happen make use of the --idempotent flag as shown below

You can also generate the script by choosing the range of migration using the argument -from and -to as shown below

Learn more about script migration

References

Summary

That concludes our tutorial on ef core migrations in entity framework core. In the next tutorial, we will look at how to reverse engineer an existing database using the migrations

2 thoughts on “EF Core Migrations”

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top