Overview Of Code First Migrations In Entity Framework

Introduction

Entity Framework code first approach allows to create POCO classes and generates or changes your new or existing database. Entity Framework has full control over the data table generation and modification using Database Initializers and Migration. Migration is a very useful concept to handle all type of Database schema changes. Using Migrations you can easily add, update, delete new or existing database.

Description

Developers always face challenges during development and during development we have to change our existing model classes or add new model classes, which may cause a mismatch schemas with existing database. In this article we are going to see database initializers and various features of Entity Framework code first migrations with examples.

Understand Database Initializers

Entity Framework code first approach create database automatically based on POCO classes. By default Database Initializers will handle this behavior. Entity Framework has basic four Database Initializers:

  1. CreateDatabaseIfNotExists
  2. DropCreateDatabaseWhenModelChanges
  3. DropCreateDatabaseAlways
  4. MigrateDatabaseToLatestVersion. MigrateDatabaseToLatestVersion is newly introduced in EF 6.0 version.

CreateDatabaseIfNotExists

Default Database Initializer class unless you declare another class. As the name suggests it will create new database if it doesn't exists.

DropCreateDatabaseWhenModelChanges

This Database Initializer class will drop and recreate the whole database whenever any data model changes found. This class is useful during starting phase of development when you don't have any concern with existing database records.

DropCreateDatabaseAlways

This class will always delete your existing database and re-create new database every time application runs. This Initializer useful when you want fresh database every time.

MigrateDatabaseToLatestVersion

This Database initializers added in Entity Framework version 6.0. This initializer is used to update the database to the latest version. This is very useful initializer to update your database scheme without deleting your database records.

You can code your custom database initializer class if you want to go beyond inbuilt database initializer classes.

Where to declare Database Initializers

The most basic approach is to declare it in your DbContext class constructor.

StudentDbContext.cs

  1. public class StudentDbContext: DbContext  
  2. {  
  3.     public StudentDbContext(): base("StudentDbContext")  
  4.     {  
  5.         Database.SetInitializer(new DropCreateDatabaseWhenModelChanges());  
  6.     }  
  7.     public DbSet < Student > Students  
  8.     {  
  9.         get;  
  10.         set;  
  11.     }  
  12.     public DbSet < Department > Departments  
  13.     {  
  14.         get;  
  15.         set;  
  16.     }  
  17. }  
Why?

If you think why Code First migrations are so important, even if we have inbuilt Database Initializers? You can read section Understanding Database Initializers which all have minor or major disadvantages. Migrations play important role when the data model changes and existing database records both are important for us. Migration can modify your existing database schema without deleting any existing records. There are two types of migrations: 
  1. Automatic
  2. Code base or Manual.
In this article we are discussing Code base or Manual Migrations.

Enabling Migrations

To enable Migrations in your project go to Tools, Library Package Manager, then Package Manager Console

Note: Select project where DataContext file located.

type below command,

PM>Enable-Migrations

package

When we fire Enable-Migrations command it will automatically check DataContext class is corresponding to any existing database or not. This command will add "Migrations" folder with Configuration class and InitialCreate migration class in the project.

Note: You can set automatic migration through writing command Enable-Migrations -EnableAutomaticMigrations,

Migrations

Configuration class

You can add the configuration level setting in constructor so it will automatically initialize when configuration class instance generate. AutomaticMigrationsEnabled= false will prevent from automatic migration every time when the application runs. you can add another property AutomaticMigrationDataLossAllowed = false, this will prevent existing data loss. Seed method used to insert default values in datatable. EF by default write comment code for sample instruction.

instruction

InitialCreate migration class

Each migration class has two methods Up() and Down(). You can update Up and Down methods for any changes. When we run migrations, Up method will call by default and update the database based on code written in its scope. Down method exactly opposite of Up method. Down method will use when we want to revert our migrations. In our example Up method is creating tables Department and Student whether in Down method, it is dropping all tables and removing all constraints.

constraints

Enable Migration command will automatically add new table __MigrationsHistory in the database. MigrationId is unique and exactly the same name as your migration name in application. ContextKey will indicate appropriate Context Model.

model
Add migrations

Please read our previous article [^], We used the same example to perform migration operations. Now add Country field in Student.cs class and add a new migration in the project,

Add migrations

Write the following command in Package Manager Console to add migration,

PM> Add migrations AddCountryToStudent

command

It will create new migration class in your Migrations folder.
  1. using System.Data.Entity.Migrations;  
  2. namespace MVCEFCodeFirstApp.Migrations  
  3. {  
  4.     public partial class AddCountryToStudent: DbMigration  
  5.     {  
  6.         public override void Up()  
  7.         {  
  8.             AddColumn("dbo.Student""Country", c => c.String());  
  9.         }  
  10.         public override void Down()  
  11.         {  
  12.             DropColumn("dbo.Student""Country");  
  13.         }  
  14.     }  
  15. }  
Update Database

When we are adding new migration don't forgot to update database for sync. To update the database write the following code in Package Manager Console. -verbose is used when you want to get SQL query.

PM>Update-Database -Verbose

update

After execute update-database command it will sync and update database.

databse

Original article link.

Reference links