What is EF Core database migration?

Suppose you shipped an app that creates a database that contains a table with two columns. While developing the next version, you figure that you will need to to modify the structure of the database to add the marvellous features that you are working on . The fastest way to do this is to delete the old database and create a fresh one with the new column. However, when users update to the new database, all previous data will be lost. This is extremely annoying in most cases. That’s where database migration comes to play

Migration consists in modifying the database from version x to version y while maintaining previous data as much as possible. Common tasks performed in a migration process are: add or remove a column, add or remove a table, etc.

Now that we understand what migrations consist of, let’s see what Entity Framework Core offers here (spoil, it is very interesting 😁)

EF Core and migrations

EF Core can handle all the migration work for you. However, EF Core needs to know the different database version. This is performed by performing an operation called “adding a migration”. Thus, the migration life-cycle can be defined as follows:

Develop the first version of the app

Before shipping: add a database migration

Ship the app

Develop new version of the app

Before shipping and if the database has been modified: add a new migration and call context.Database.Migrate(); before the first database operation

Ship the app

Repeat steps 4, 5 and 6 for each new version.

Okay, let’s dive into some code and details. In this following, we will try to achieve to following use case:

Making the first database migration

As indicated earlier, the first step consists in making database able to handle EF Core migrations. We achieve this by adding a migration on the first version of the app. You can start working on this commit:

We are ready to add our first migration. Open up the terminal by right clicking on the projet -> Tools -> Terminal and run the following commands:

dotnet restore (this ensures that we have all the required packages)

dotnet ef migrations add InitialMigration (create the 1st migration)

After executing these commands, the database becomes migration aware and can handle future updates to its structure.

The last step here is to tell EF Core in the code to create the database by taking migration into account. It consists in replacing context.Database.EnsureCreated() by context.Database.Migrate() .

The program.cs class should look like this:

We can ship the first version of the app serenely because future migrations will be handled by EF Core. And that’s exactly what we are going to do in the next section.

Creating a migration for a new version of the database

Now that we have prepared the database fro migration and shipped it to our users. Let’s tackle the next version by adding a column to the VideoGame class:

We will add now a new migration that will handle the transition from the previous version of the database to the new version.

dotnet ef migrations add Version2

This migration allows EF Core to estimate the delta between the previous database migration and the current one. Thus, EF Core will be able to handle both of these situations: if there is no database when the app starts, EF Core will create one. If an older version of the database is found, EF Core will follow the migration plan until it reaches the last database version.

In the code, never call context.Database.EnsureDeleted() because we don’t want the database to be deleted (the migration will be useless otherwise). Do not also forget to call context.Database.Migrate() before querying the database.

And now, the time for experimentation has finally come!

Let’s experiment

In order to experiment migrations, we will need to run the first version of the app, add some data to it, and then run the last version an check if EF core kept the old data while adding the new column.

I have hopefully prepared two separate commits; one for the 1st version and an other for the next version.

This first commit corresponds to the first version of the app. So clone the repository, update to the following commit and run the app.

Run the app, you should notice in the output the the video games that were saved in the previous version as well as the new data added in the current execution. You should also note that RealeseDate of previous data is set to 0.

You have succeffully used your first EF Core migration :)

Conclusion

This article has guided you through the process of database migrations using EF Core. For the sake of diversity, we used Visual Studio 2017 instead of VSCode. After experimenting with EF Core migrations, I find it very easy while being very powerful. However, the only caveat is to remember to add a migration of the initial database before the first release.