Entity Framework Core Migrations

Understanding Entity Framework Core Migrations

Migrations in Entity Framework Core are a way to keep your application's model structure synchronized with the database. They provide a straightforward mechanism for updating your code and ensuring that the database schema evolves accordingly. With Entity Framework Core, managing migrations is made easy and efficient.

In this blog post, we'll use the code from our previous article, which you can find on our GitHub repository. This code serves as a starting point for our migration examples.

Implementing Migrations in Entity Framework Core

Let's begin by generating migrations. There are two options to achieve this:

Option A: Using the command line, navigate to the folder containing the project's csproj file that includes the DbContext. Execute the following code:

csharpCopy codedotnet ef migrations add InitialMigration

Option B: In the NuGet Package Manager Console, execute the following command:

sqlCopy codeAdd-Migration InitialMigration

Both options will generate three files as a result:

  1. The main migration file, which contains the Up and Down operations. By opening this file, you can see that Up includes the code for creating the database, while Down includes the code for undoing the changes made by Up.

  2. The designer file, which contains metadata used by Entity Framework Core.

  3. The snapshot file, which represents a snapshot of the current model. Entity Framework Core uses this file to detect changes since the last migration.

To execute the migrations and ensure that the database schema matches the code, add the following code to your Startup.cs file:

csharpCopy codeusing (var scope = app.Services.CreateScope())
{
    ejemploEFContext context = scope.ServiceProvider.GetRequiredService<ejemploEFContext>();
    context.Database.Migrate();
}

Running the project will now create the necessary tables and an additional table that keeps track of the executed migrations.

Updating a Database with Migrations in Entity Framework Core

Migrations, being part of the code-first approach, allow us to update the database through the migrations themselves. Let's illustrate this with an example. Suppose we want to add a new field called Email to the Users table. To do this, follow these steps:

  1. Add the Email property to the User entity class:
csharpCopy codepublic class User
{
    public int Id { get; set; }
    public string UserName { get; set; }
    [MaxLength(50)]
    public string Email { get; set; }
}
  1. Create a new migration using the following command:
csharpCopy codedotnet ef migrations add AddEmailToUser

This command will generate a new migration file with the Up and Down operations.

  1. Execute the project, and Entity Framework will automatically update the database to reflect the changes in your code. The new migration will add the Email column to the Users table, and the migration table will record this update.

Reverting a Migration in Entity Framework Core

In case you need to revert a migration due to an error or the need to roll back to a previous version, Entity Framework Core provides a simple process. To revert a migration, follow these steps:

  1. Execute the following command in the command line or the Package Manager Console, replacing <PreviousVersionName> with the name of the migration to which you want to revert:

Command Line:

phpCopy codedotnet ef database update <PreviousVersionName>

Package Manager Console:

mathematicaCopy codeUpdate-Database <PreviousVersionName>
  1. Entity Framework Core will revert the migration and display a message indicating that the migration has been successfully rolled back. The database will reflect the state of the previous version, allowing you to safely deploy the older version of your code.

Note: If you remove the code from the Down method in the migration file, the revert operation will have no effect.

Removing a Migration

If you need to remove a migration that was created erroneously, simply deleting the migration file is not enough, as the snapshot file is modified. To properly remove a migration, use the following command:

arduinoCopy codedotnet ef migrations remove

This command will remove the latest migration and restore the snapshot file to its previous state.

Adding Initial Data with Entity Framework Core Data Seeding

Data seeding, or importing initial data, is a useful feature in Entity Framework Core. It allows you to preload reference or static data into your database when the application starts. Let's explore how to implement data seeding using migrations.

To add data seeding, we leverage the OnModelCreating method within our DbContext class. This method contains the configuration for the database, tables, and migrations. Here's an example of how to import default users:

csharpCopy codepublic class ejemploEFContext : DbContext
{
    public virtual DbSet<User> Users { get; set; }
    public virtual DbSet<jobexperiencie> jobexperiencies { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder.UseMySQL("server=127.0.0.1;port=4306;database=ejemploEF;user=root;password=ejemploEFpass");

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasData(
            new User { Email = "example1@mail.com", Id = 1, UserName = "user1" },
            new User { Email = "user2@mail.com", Id = 2, UserName = "user2" }
        );
    }
}

In this example, we define the initial data within the OnModelCreating method by using the HasData method of the Entity builder. The defined users will be inserted into the Users table upon the execution of migrations.

To invoke the data seeding class, add the following code within the OnModelCreating method:

csharpCopy codemodelBuilder.ApplyConfiguration(new UserSeed());

Now, when you create a migration, the corresponding Up and Down methods will include the code for inserting and deleting the seeded data, respectively.

By mastering Entity Framework Core migrations and data seeding, you can ensure that your database evolves seamlessly with your application, making it easy to manage and maintain over time.