English 中文(简体)
Entity Framework Tutorial

Entity Framework Resources

Selected Reading

Entity F - Code First Migration
  • 时间:2024-11-05

Entity Framework - Code First Migration


Previous Page Next Page  

Entity Framework 4.3 includes a new Code First Migrations feature that allows you to incrementally evolve the database schema as your model changes over time. For most developers, this is a big improvement over the database initiapzer options from the 4.1 and 4.2 releases that required you to manually update the database or drop and recreate it when your model changed.

    Before Entity Framework 4.3, if you already have data (other than seed data) or existing Stored Procedures, triggers, etc. in your database, these strategies used to drop the entire database and recreate it, so you would lose the data and other DB objects.

    With migration, it will automatically update the database schema, when your model changes without losing any existing data or other database objects.

    It uses a new database initiapzer called MigrateDatabaseToLatestVersion.

There are two kinds of Migration −

    Automated Migration

    Code based Migration

Automated Migration

Automated Migration was first introduced in Entity framework 4.3. In automated migration you don t need to process database migration manually in the code file. For example, for each change you will also need to change in your domain classes. But with automated migration you just have to run a command in Package Manager Console to get done this.

Let’s take a look at the following step-by-step process of automated migration.

When you use Code First approach, you don t have a database for you apppcation.

In this example we will be starting with our 3 basic classes such as Student, Course and Enrollment as shown in the following code.

pubpc class Enrollment {
   pubpc int EnrollmentID { get; set; }
   pubpc int CourseID { get; set; }
   pubpc int StudentID { get; set; }
   pubpc Grade? Grade { get; set; }
	
   pubpc virtual Course Course { get; set; }
   pubpc virtual Student Student { get; set; }

}

pubpc class Student {
   pubpc int ID { get; set; }
   pubpc string LastName { get; set; }
   pubpc string FirstMidName { get; set; }
   pubpc DateTime EnrollmentDate { get; set; }
	
   pubpc virtual ICollection<Enrollment> Enrollments { get; set; }

}

pubpc class Course {
   pubpc int CourseID { get; set; }
   pubpc string Title { get; set; }
   [Index]
   pubpc int Credits { get; set; }
	
   pubpc virtual ICollection<Enrollment> Enrollments { get; set; }

}

Following is the context class.

pubpc class MyContext : DbContext {
   pubpc MyContext() : base("MyContextDB") {}
   pubpc virtual DbSet<Course> Courses { get; set; }
   pubpc virtual DbSet<Enrollment> Enrollments { get; set; }
   pubpc virtual DbSet<Student> Students { get; set; }
}

Before running the apppcation, you need to enable automated migration.

Step 1 − Open Package Manger Console from Tools → NuGet Package Manger → Package Manger Console.

Step 2 − To enable automated migration run the following command in Package Manager Console.

PM> enable-migrations -EnableAutomaticMigrations:$true
Command

Step 3 − Once the command runs successfully, it creates an internal sealed Configuration class in the Migration folder of your project as shown in the following code.

namespace EFCodeFirstDemo.Migrations {

   using System;
   using System.Data.Entity;
   using System.Data.Entity.Migrations;
   using System.Linq;
	
   internal sealed class Configuration : DbMigrationsConfiguration<EFCodeFirstDemo.MyContext> {

      pubpc Configuration() {
         AutomaticMigrationsEnabled = true;
         ContextKey = "EFCodeFirstDemo.MyContext";
      }

      protected override void Seed(EFCodeFirstDemo.MyContext 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 duppcate seed data. E.g.

         //  context.People.AddOrUpdate(
            //  p ⇒ p.FullName, 
            //  new Person { FullName = "Andrew Peters" }, 
            //  new Person { FullName = "Brice Lambson" }, 
            //  new Person { FullName = "Rowan Miller" }
         //  );
      }
   }
}

Step 4 − Set the database initiapzer in the context class with the new DB initiapzation strategy MigrateDatabaseToLatestVersion.

pubpc class MyContext : DbContext {

   pubpc MyContext() : base("MyContextDB") {
      Database.SetInitiapzer(new MigrateDatabaseToLatestVersion<MyContext, 
         EFCodeFirstDemo.Migrations.Configuration>("MyContextDB"));
   }

   pubpc virtual DbSet<Course> Courses { get; set; }
   pubpc virtual DbSet<Enrollment> Enrollments { get; set; }
   pubpc virtual DbSet<Student> Students { get; set; }

}

Step 5 − You have set up automated migration. When you execute your apppcation, then it will automatically take care of migration, when you change the model.

Migration

Step 6 − As you can see that one system table __MigrationHistory is also created in your database with other tables. In __MigrationHistory, automated migration maintains the history of database changes.

Step 7 − When you add another entity class as your domain class and execute your apppcation, then it will create the table in your database. Let’s add the following StudentLogIn class.

pubpc class StudentLogIn {
   [Key, ForeignKey("Student")]
   pubpc int ID { get; set; }
   pubpc string EmailID { get; set; }
   pubpc string Password { get; set; }
	
   pubpc virtual Student Student { get; set; }
}

Step 8 − Don’t forget to add the DBSet for the above mentioned class in your context class as shown in the following code.

pubpc virtual DbSet<StudentLogIn> StudentsLogIn { get; set; }

Step 9 − Run your apppcation again and you will see that StudentsLogIn table is added to your database.

StudentsLogIn

The above steps mentioned for automated migrations will only work for your entity. For example, to add another entity class or remove the existing entity class it will successfully migrate. But if you add or remove any property to your entity class then it will throw an exception.

Step 10 − To handle the property migration you need to set AutomaticMigrationDataLossAllowed = true in the configuration class constructor.

pubpc Configuration() {
   AutomaticMigrationsEnabled = true;
   AutomaticMigrationDataLossAllowed = true;
   ContextKey = "EFCodeFirstDemo.MyContext";
}

Code Based Migration

When you develop a new apppcation, your data model changes frequently, and each time the model changes, it gets out of sync with the database. You have configured the Entity Framework to automatically drop and re-create the database each time you change the data model. Code-based migration is useful when you want more control on the migration.

    When you add, remove, or change entity classes or change your DbContext class, the next time you run the apppcation it automatically deletes your existing database, creates a new one that matches the model, and seeds it with test data.

    The Code First Migrations feature solves this problem by enabpng Code First to update the database schema instead of dropping and re-creating the database. To deploy the apppcation, you ll have to enable Migrations.

Here is the basic rule to migrate changes in the database −

    Enable Migrations

    Add Migration

    Update Database

Let’s take a look at the following step-by-step process of code-base migration.

When you use code first approach, you don t have a database for you apppcation.

In this example we will be starting again with our 3 basic classes such as Student, Course and Enrollment as shown in the following code.

pubpc class Enrollment {
   pubpc int EnrollmentID { get; set; }
   pubpc int CourseID { get; set; }
   pubpc int StudentID { get; set; }
   pubpc Grade? Grade { get; set; }
	
   pubpc virtual Course Course { get; set; }
   pubpc virtual Student Student { get; set; }

}

pubpc class Student {
   pubpc int ID { get; set; }
   pubpc string LastName { get; set; }
   pubpc string FirstMidName { get; set; }
   pubpc DateTime EnrollmentDate { get; set; }
	
   pubpc virtual ICollection<Enrollment> Enrollments { get; set; }

}

pubpc class Course {
   pubpc int CourseID { get; set; }
   pubpc string Title { get; set; }
   [Index]
   pubpc int Credits { get; set; }
	
   pubpc virtual ICollection<Enrollment> Enrollments { get; set; }

}

Following is the context class.

pubpc class MyContext : DbContext {

   pubpc MyContext() : base("MyContextDB") {
      Database.SetInitiapzer(new MigrateDatabaseToLatestVersion<
         MyContext, EFCodeFirstDemo.Migrations.Configuration>("MyContextDB"));
   }

   pubpc virtual DbSet<Course> Courses { get; set; }
   pubpc virtual DbSet<Enrollment> Enrollments { get; set; }
   pubpc virtual DbSet<Student> Students { get; set; }

}

Step 1 − Before running the apppcation you need to enable migration.

Step 2 − Open Package Manager Console from Tools → NuGet Package Manger → Package Manger Console.

Step 3 − Migration is already enabled, now add migration in your apppcation by executing the following command.

PM> add-migration "UniDB Schema"

Step 4 − When the command is successfully executed then you will see a new file has been created in the Migration folder with the name of the parameter you passed to the command with a timestamp prefix as shown in the following image.

TimeStamp Prefix

Step 5 − You can create or update the database using the “update-database” command.

PM> Update-Database -Verbose

The "-Verbose" flag specifies to show the SQL Statements being appped to the target database in the console.

Step 6 − Let’s add one more property ‘Age’ in the student class and then execute the update statement.

pubpc class Student {
   pubpc int ID { get; set; }
   pubpc string LastName { get; set; }
   pubpc string FirstMidName { get; set; }
   pubpc int Age { get; set; }
   pubpc DateTime EnrollmentDate { get; set; }
	
   pubpc virtual ICollection<Enrollment> Enrollments { get; set; }

}

When you execute PM → Update-Database –Verbose, when the command is successfully executed you will see that the new column Age is added in your database.

New Column Age.

We recommend that you execute the above example in a step-by-step manner for better understanding.

Advertisements