Code-Based Migration in Entity Framework Code First

Code-Based Migration in Entity Framework Code First Approach

In this article, I am going to discuss Code-Based Database Migration in Entity Framework Code-First Approach with Examples. Please read our previous article where we discussed Automated Migration in Entity Framework Code-First Approach. The Automated Migration automatically updates the database schema when we change our domain classes. Now, in this article, you will learn about Code-Based Migration.

Code-Based Migration in Entity Framework Code First Approach

The Code-Based Database Migration in Entity Framework Code First Approach provides more control over the migration and allows us to configure additional things such as setting a default value of a column, configuring a computed column, etc. In order to use Code-Based Migration in Entity Framework, we need to execute the following commands in the Package Manager Console in Visual Studio:

  1. Enable-Migrations: This will enable the migration in our project by creating the Configuration class within the Migration folder in our application.
  2. Add-Migration: This will create a new migration class as per the specified name with the Up() and Down() methods.
  3. Update-Database: This will execute the last migration file created by the Add-Migration command and applies changes to the database schema.

If the above commands are not clear at the moment, then don’t worry, we will understand the above commands with examples.

Example to Understand Code-Based Database Migration in Entity Framework Code-First

First, create a new console application with the name EFCodeFirstMigrationDemo. Then install the Entity Framework Latest Version from the Manage NuGet Packages for Solution. Once you install the Entity Framework, then create the following Student and Standard Entities.

Student.cs

Create a class file with the name Student.cs and then copy and paste the following code into it.

namespace EFCodeFirstMigrationDemo
{
    public class Student
    {
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int StandardId { get; set; }
        public Standard Standard { get; set; }
    }
}
Standard.cs

Create a class file with the name Standard.cs and then copy and paste the following code into it.

using System.Collections.Generic;
namespace EFCodeFirstMigrationDemo
{
    public class Standard
    {
        public int StandardId { get; set; }
        public string StandardName { get; set; }
        public string Description { get; set; }
        public ICollection<Student> Students { get; set; }
    }
}

Please make sure to have the connection string with the name MyConnectionString within the app.config file as shown in the below image.

Example to Understand Code-Based Database Migration in Entity Framework Code-First

Creating the Context Class:

Create a class file with the name EFCodeFirstMigrationContext.cs and then copy and paste the following code. Later, we will update this context class as per our requirements.

using System.Data.Entity;
namespace EFCodeFirstMigrationDemo
{
    class EFCodeFirstMigrationContext : DbContext
    {
        public EFCodeFirstMigrationContext() : base("name=MyConnectionString")
        {
        }

        public DbSet<Student> Students { get; set; }
        public DbSet<Standard> Standards { get; set; }
    }
}
Enable-Migrations Command in Entity Framework:

This command will enable migration in our project by creating the Configuration class within the Migration folder in our application. In order to use Code-Based Migrations in Entity Framework Code First Approach, first we need to execute the Enable-Migrations command in the Package Manager Console. To do so, open the Package Manager Console from Tools → NuGet Package Manager → Package Manager Console as shown in the below image.

Enable-Migrations Command in Entity Framework

Once you open the Package Manager Console, then run the Enable-Migrations command (make sure that the default project is the project where your context class is located) and press the enter button as shown in the below image.

Enable-Migrations command

Once the above Enable-Migrations command is executed successfully, it will create the following Configuration class within the Migration folder. This class is derived from the DbMigrationsConfiguration class and this time it will set the AutomaticMigrationsEnabled value to false. Later, we will update this class as per our requirements.

namespace EFCodeFirstMigrationDemo.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<EFCodeFirstMigrationDemo.EFCodeFirstMigrationContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(EFCodeFirstMigrationDemo.EFCodeFirstMigrationContext context)
        {
            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet<T>.AddOrUpdate() helper extension method
            //  to avoid creating duplicate seed data.
        }
    }
}

Next, we need to set the database initializer as MigrateDatabaseToLatestVersion in our context class. So, modify the context class as follows.

using System.Data.Entity;
namespace EFCodeFirstMigrationDemo
{
    class EFCodeFirstMigrationContext : DbContext
    {
        public EFCodeFirstMigrationContext() : base("name=MyConnectionString")
        {
            //Setting the Database Initializer as MigrateDatabaseToLatestVersion
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<EFCodeFirstMigrationContext, EFCodeFirstMigrationDemo.Migrations.Configuration>());
        }

        public DbSet<Student> Students { get; set; }
        public DbSet<Standard> Standards { get; set; }
    }
}
Add-Migration Command in Entity Framework:

This Add-Migration Command will create a new migration class as per the specified name with the Up() and Down() methods. So, let us create the Migration class with the name MyMigration-V1 (you can give any name as per your wish) using the Add-Migration command in Package Manager Console. Open Package Manager Console and then type the command as Add-Migration MyMigration-V1 and press the enter button as shown in the below image.

Add-Migration Command in Entity Framework

If the above command is executed successfully, then you will see the following message in the Package Manager Console.

Add-Migration Command in Entity Framework

Once the command is executed successfully, then you will see that, it will create a <TimeStamp>_MyMigration-V1.cs i.e. in our case 202302060632553_MyMigration-V1.cs file with the Up() and Down() methods. If you open the class file, then you will see the following code. As you can see in the below code, the Up() method contains code for creating database objects. On the other hand, the Down() method contains code for dropping or deleting database objects such as Tables, Indexes, Keys, etc. If you want, then you can also write your own custom code for additional configurations. This is the advantage over automated migration.

namespace EFCodeFirstMigrationDemo.Migrations
{
    using System;
    using System.Data.Entity.Migrations;
    
    public partial class MyMigrationV1 : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.Standards",
                c => new
                    {
                        StandardId = c.Int(nullable: false, identity: true),
                        StandardName = c.String(),
                        Description = c.String(),
                    })
                .PrimaryKey(t => t.StandardId);
            
            CreateTable(
                "dbo.Students",
                c => new
                    {
                        StudentId = c.Int(nullable: false, identity: true),
                        FirstName = c.String(),
                        LastName = c.String(),
                        StandardId = c.Int(nullable: false),
                    })
                .PrimaryKey(t => t.StudentId)
                .ForeignKey("dbo.Standards", t => t.StandardId, cascadeDelete: true)
                .Index(t => t.StandardId);
            
        }
        
        public override void Down()
        {
            DropForeignKey("dbo.Students", "StandardId", "dbo.Standards");
            DropIndex("dbo.Students", new[] { "StandardId" });
            DropTable("dbo.Students");
            DropTable("dbo.Standards");
        }
    }
}
Update-Database Command in Entity Framework:

This Command will execute the last migration file which is created by the Add-Migration command and applies changes to the database schema. In this case, the last generated file is 202302060632553_MyMigration-V1.cs.

Once we create the migration file using the Add-Migration command, then we have to update the database. For updating the database, we need to execute the Update-Database command to create or modify the database schema in the database. If you want to see the generated SQL Statement, then you need to use the –verbose option along with the Update-Database command. So, open Package Manager Console and then type Update-Database –Verbose command and press the enter button as shown in the below image.

Update-Database Command in Entity Framework

Once the Command is executed successfully, the database should be created or updated. If you verify the database, then you should see the following.

Update-Database Command in Entity Framework

Now, whenever you change the domain classes, execute the Add-Migration command with the name parameter to create a new migration file and then again execute the Update-Database command to apply the changes to the database schema. For a better understanding, let us modify the Student Entity as follows. Here, we have removed the LastName Property and we have added the Branch Property.

namespace EFCodeFirstMigrationDemo
{
    public class Student
    {
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string Branch { get; set; }
        public int StandardId { get; set; }
        public Standard Standard { get; set; }
    }
}

Next, add the following Course Entity.

namespace EFCodeFirstMigrationDemo
{
    public class Course
    {
        public int CourseId { get; set; }
        public string CourseName { get; set; }
        public string Description { get; set; }
    }
}

Next, modify the context class as follows.

using System.Data.Entity;
namespace EFCodeFirstMigrationDemo
{
    class EFCodeFirstMigrationContext : DbContext
    {
        public EFCodeFirstMigrationContext() : base("name=MyConnectionString")
        {
            //Setting the Database Initializer as MigrateDatabaseToLatestVersion
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<EFCodeFirstMigrationContext, EFCodeFirstMigrationDemo.Migrations.Configuration>());
        }

        public DbSet<Student> Students { get; set; }
        public DbSet<Standard> Standards { get; set; }
        public DbSet<Course> Courses { get; set; }
    }
}

With the above changes in place, open the Package Manager Console and execute the Add-Migration MyMigration-V2 command as shown in the below image. Here, we are providing the migration name MyMigration-V2.

Code-Based Database Migration in Entity Framework Code-First Approach with Examples

Once you execute the above command, then you will see that another .cs class file with the name <TimeStamp_> MyMigration-V2 will be created within the Migration Folder as shown in the below image.

Code-Based Database Migration in Entity Framework Code-First Approach with Examples

Once you open the above class file, then you will see the following code. The Up method is containing the code to add the Courses table as well as it contains the code to update the Students table i.e. adding the Branch column and dropping the LastName column.

namespace EFCodeFirstMigrationDemo.Migrations
{
    using System;
    using System.Data.Entity.Migrations;
    
    public partial class MyMigrationV2 : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.Courses",
                c => new
                    {
                        CourseId = c.Int(nullable: false, identity: true),
                        CourseName = c.String(),
                        Description = c.String(),
                    })
                .PrimaryKey(t => t.CourseId);
            
            AddColumn("dbo.Students", "Branch", c => c.String());
            DropColumn("dbo.Students", "LastName");
        }
        
        public override void Down()
        {
            AddColumn("dbo.Students", "LastName", c => c.String());
            DropColumn("dbo.Students", "Branch");
            DropTable("dbo.Courses");
        }
    }
}

Next, open Package Manager Console and then type Update-Database –Verbose command and press the enter button as shown in the below image.

Update-Database –Verbose command

Once the Command is executed successfully, the database should be created or updated as expected. If you verify the database, then you should see the following.

Update-Database –Verbose command

Rollback Migration in Entity Framework Code First Approach

If you want to roll back the database schema to any of the previous states i.e. to any of the Migration Versions, then you need to execute the Update-Database command with the –TargetMigration parameter to the point which you want to roll back to. For example, we have created two migrations (MyMigration-V1 and MyMigration-V2) which are applied to the EFCodeFirstDB database but we want to roll back to the first migration. Then we need to execute the Update-Database -TargetMigration:MyMigration-V1 command in the Package Manager Console as shown in the below image.

Rollback Migration in Entity Framework Code First Approach

Now, verify the database and you should see the following. You can see the LastName column is in the Students table. The Course table is also dropped from the database.

Rollback Migration in Entity Framework Code First Approach

In the next article, I am going to discuss Entity Framework Core with Examples. Here, in this article, I try to explain Code-Based Database Migration in Entity Framework Code-First Approach with Examples. I hope you enjoy this Code-Based Migration in Entity Framework Code-First Approach article. Please give your valuable feedback and suggestions about this article.

Leave a Reply

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