The official source of information on Managed Providers, DataSet & Entity Framework from Microsoft
The information in this post is out of date.
Visit msdn.com/data/ef for the latest information on current and past releases of EF.
For Automatic Migrations see http://msdn.com/data/jj554735
We have released the final preview of the Code First Migrations work as part of Entity Framework 4.3 Beta 1.
This post will provide an overview of the functionality that is available inside of Visual Studio for interacting with migrations. We will focus on the workflow that combines automatic and code-based migrations. In this workflow most changes can be automatically calculated and applied. More complex changes are written out to code-based migrations that reside in your project.
There is a separate EF 4.3 Beta 1: Code-Based Migrations Walkthrough that shows how this same set of changes can be applied using purely code-based migrations.
This post assumes you have a basic understanding of Code First, if you are not familiar with Code First then please complete the Code First Walkthrough.
Before we start using migrations we need a project and a Code First model to work with. For this walkthrough we are going to use the canonical Blog and Post model.
using System.Data.Entity; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Data.Entity.Infrastructure; namespace MigrationsAutomaticDemo { public class BlogContext : DbContext { public DbSet<Blog> Blogs { get; set; } } public class Blog { public int BlogId { get; set; } public string Name { get; set; } } }
Now that we have a Code First model, let’s enable Migrations to work with our context.
namespace MigrationsAutomaticDemo.Migrations { using System; using System.Data.Entity; using System.Data.Entity.Migrations; using System.Linq; internal sealed class Configuration : DbMigrationsConfiguration<MigrationsAutomaticDemo.BlogContext> { public Configuration() { AutomaticMigrationsEnabled = true; } protected override void Seed(MigrationsAutomaticDemo.BlogContext 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. E.g. // // context.People.AddOrUpdate( // p => p.FullName, // new Person { FullName = "Andrew Peters" }, // new Person { FullName = "Brice Lambson" }, // new Person { FullName = "Rowan Miller" } // ); // } } }
Code First Migrations has two commands that you are going to become familiar with. Add-Migration will scaffold a code-based migration based on changes you have made to your model. Update-Database will apply any pending changes to the database. We are going to avoid using Add-Migration (unless we really need to) and focus on letting Code First Migrations automatically calculate and apply the changes.
Let’s make another change and let Code First Migrations automatically push the changes to the database for us.
public class Blog { public int BlogId { get; set; } public string Name { get; set; } public List<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } [MaxLength(200)] public string Title { get; set; } public string Content { get; set; } public int BlogId { get; set; } public Blog Blog { get; set; } }
.
Now let’s look at something we might want to use a code-based migration for.
public class Blog { public int BlogId { get; set; } public string Name { get; set; } public int Rating { get; set; } public List<Post> Posts { get; set; } }
namespace MigrationsAutomaticDemo.Migrations { using System.Data.Entity.Migrations; public partial class MyFirstCodeMigration : DbMigration { public override void Up() { AddColumn("Blogs", "Rating", c => c.Int(nullable: false, defaultValue: 3)); } public override void Down() { DropColumn("Blogs", "Rating"); } } }
Fortunately we don’t have to keep using code-based migrations now, we can switch back to automatic migrations for our simpler changes. Code First Migrations will take care of performing the automatic and code-based migrations in the correct order based on the metadata it is storing in the code-behind file for each code-based migration.
public class Post { public int PostId { get; set; } [MaxLength(200)] public string Title { get; set; } public string Content { get; set; } public string Abstract { get; set; } public int BlogId { get; set; } public Blog Blog { get; set; } }
So far we have just looked at migration operations that can leave all the data in place, now let’s look at something that needs to move some data around. There is no native support for data motion yet, but we can run some arbitrary SQL commands at any point in our script.
We just added the Abstract column. Let’s pre-populate it for existing posts using text from the Content column.
namespace MigrationsAutomaticDemo.Migrations { using System.Data.Entity.Migrations; public partial class PopulatePostAbstract : DbMigration { public override void Up() { Sql("UPDATE dbo.Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL"); } public override void Down() { } } }
Our edited migration looks good, so let’s use Update-Database to bring the database up-to-date. We’ll specify the –Verbose flag so that we can see the SQL being run against the database.
So far we have always upgraded to the latest migration, but there may be times when you want upgrade/downgrade to a specific migration.
This command will run the Down script for our PopulatePostAbstract migration, then use the automatic pipeline to revert the addition of the Abstract column.
If you want to roll all the way back to an empty database then you can use the Update-Database –TagetMigration:"0" command.
Now that we have performed a few iterations on our local database let’s look at applying those same changes to another database.
If another developer wants these changes on their machine they can just sync once we check our changes into source control. Once they have our new migrations they can just run the Update-Database command to have the changes applied locally. However if we want to push these changes out to a test server, and eventually production, we probably want a SQL script we can hand off to our DBA.
NOTE: There are a number of bugs in the scripting functionality in EF 4.3 Beta1 that prevent you generating a script starting from a migration other than an empty database. These bugs will be fixed in the final RTM.
In this walkthrough you saw how to use automatic migrations to push model changes to the database. You saw how to scaffold and run code-based migrations when you need more control. You also saw how to upgrade and downgrade your database. Finally we looked at how to get a SQL script that represents the pending changes to a database.
Rowan Miller Program Manager ADO.NET Entity Framework