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 Code First Migrations see http://msdn.com/data/jj591621
We have released the first go-live release of our Code First Migrations work as part of Entity Framework 4.3.
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 code-based workflow for using migrations. In this workflow each change is written out to a code-based migration that can reside in your project.
There is a separate Automatic Migrations Walkthrough that shows how this same set of changes can be applied using a mixture of code-based and automatic 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 MigrationsCodeDemo { 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 model it’s time to use it to perform data access. Update the Program.cs file with the code shown below.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MigrationsCodeDemo { class Program { static void Main(string[] args) { using (var db = new BlogContext()) { db.Blogs.Add(new Blog { Name = "Another Blog " }); db.SaveChanges(); foreach (var blog in db.Blogs) { Console.WriteLine(blog.Name); } } } } }
Run your application and you will see that a MigrationsCodeDemo.BlogContext database is created on your local SQLEXPRESS instance.
It’s time to make some more changes to our model.
public class Blog { public int BlogId { get; set; } public string Name { get; set; } public string Url { get; set; } }
Code First Migrations has two commands that you are going to become familiar with.
namespace MigrationsCodeDemo.Migrations { using System.Data.Entity.Migrations; public partial class AddBlogUrl : DbMigration { public override void Up() { AddColumn("Blogs", "Url", c => c.String()); } public override void Down() { DropColumn("Blogs", "Url"); } } }
So far we’ve generated and run a migration without making any changes. Now let’s look at editing the code that gets generated by default.
public class Blog { public int BlogId { get; set; } public string Name { get; set; } public string Url { get; set; } public int Rating { 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; } }
namespace MigrationsCodeDemo.Migrations { using System.Data.Entity.Migrations; public partial class AddPostClass : DbMigration { public override void Up() { CreateTable( "Posts", c => new { PostId = c.Int(nullable: false, identity: true), Title = c.String(maxLength: 200), Content = c.String(), BlogId = c.Int(nullable: false), }) .PrimaryKey(t => t.PostId) .ForeignKey("Blogs", t => t.BlogId, cascadeDelete: true) .Index(t => t.BlogId) .Index(p => p.Title, unique: true); AddColumn("Blogs", "Rating", c => c.Int(nullable: false, defaultValue: 3)); } public override void Down() { DropIndex("Posts", new[] { "BlogId" }); DropForeignKey("Posts", "BlogId", "Blogs"); DropColumn("Blogs", "Rating"); DropTable("Posts"); } } }
So far we have looked at migration operations that don’t change or move any data, 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.
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; } }
namespace MigrationsCodeDemo.Migrations { using System.Data.Entity.Migrations; public partial class AddPostAbstract : DbMigration { public override void Up() { AddColumn("Posts", "Abstract", c => c.String()); Sql("UPDATE Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL"); } public override void Down() { DropColumn("Posts", "Abstract"); } } }
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 AddBlogAbstract and AddPostClass migrations.
If you want to roll all the way back to an empty database then you can use the Update-Database –TargetMigration:$InitialDatabase command.
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.
In this walkthrough you saw how to scaffold, edit and run code-based migrations to upgrade and downgrade your database. You also saw how to get a SQL script to apply migrations to a database.
Rowan Miller Program Manager ADO.NET Entity Framework