首页 > 代码库 > Entity Framework Code First Migrations 官方Demo

Entity Framework Code First Migrations 官方Demo

一、建立初始模型和数据库

1、创建一个新的控制台程序 MigrationsDemo 。

2、安装最新的 EntityFramework NuGet 程序包

打开程序包管理器控制台 -> 运行命令 Install-Package EntityFramework 

3、创建名为 Model.cs 的文件,代码如下,其中定义了一个组成领域模型的 Blog 类,和一个 EF Code First 上下文类 BlogContext 。

 1     using System.Data.Entity;
 2     using System.Collections.Generic;
 3     using System.ComponentModel.DataAnnotations;
 4     using System.Data.Entity.Infrastructure;
 5 
 6     namespace MigrationsDemo
 7     {
 8         public class BlogContext : DbContext
 9         {
10             public DbSet<Blog> Blogs { get; set; }
11         }
12 
13         public class Blog
14         {
15             public int BlogId { get; set; }
16             public string Name { get; set; }
17         }
18     }

4、更改 Program.cs 文件的代码

 1     using System;
 2     using System.Collections.Generic;
 3     using System.Linq;
 4     using System.Text;
 5 
 6     namespace MigrationsDemo
 7     {
 8         class Program
 9         {
10             static void Main(string[] args)
11             {
12                 using (var db = new BlogContext())
13                 {
14                     db.Blogs.Add(new Blog { Name = "Another Blog " });
15                     db.SaveChanges();
16 
17                     foreach (var blog in db.Blogs)
18                     {
19                         Console.WriteLine(blog.Name);
20                     }
21                 }
22 
23                 Console.WriteLine("Press any key to exit...");
24                 Console.ReadKey();
25             }
26         }
27     }

5、配置 App.config 中的数据库连接字符串(与本地SqlServer数据库连接)。

1 <configuration>
2   <connectionStrings>
3     <add name="BlogContext" connectionString="Data Source=.;Initial Catalog= BlogContext;Integrated Security=True" providerName="System.Data.SqlClient" />
4   </connectionStrings>
5 </configuration>

 6、运行程序,在SqlServer中自动生成数据库。

技术分享

 

二、实现迁移

向 Blog 类添加 Url 属性。

public string Url { get; set; }

如果直接运行程序,会报错。

技术分享

实现上下文的迁移:打开程序包管理器控制台 -> 运行命令 Enable-Migrations

命令执行后,在项目中生成了一个 Migrations 文件夹,包含两个文件:Configuration 类,InitialCreate迁移。

技术分享

多个模型指向同一个数据库

在 Configuration 文件中,包含了 ContextKey 属性,作为 Code First 模型的唯一识别符。

 

三、生成并运行迁移

Code First 迁移有两个主要命令:

Add-Migration :基于上次迁移后所作出的改变,搭建接下来的迁移支架。

Update-Database :将所有的待执行迁移应用到数据库

1、在程序包管理器控制台执行命令 Add-Migration AddBlogUrl  (AddBlogUrl  :Add-Migration 允许我们给这些迁移命名)。

2、在 Migrations 文件夹中,生成了AddBlogUrl  迁移,如下所示。

 1 namespace MigrationsDemo.Migrations
 2     {
 3         using System;
 4         using System.Data.Entity.Migrations;
 5         
 6         public partial class AddBlogUrl : DbMigration
 7         {
 8             public override void Up()
 9             {
10                 AddColumn("dbo.Blogs", "Url", c => c.String());
11             }
12             
13             public override void Down()
14             {
15                 DropColumn("dbo.Blogs", "Url");
16             }
17         }
18     }

3、执行命令 Update-Database,数据库被更新(Blogs 表中包含了 Url 列)。

 

四、定制迁移

在 Blog 类中添加 Rating 属性

public int Rating { get; set; }

添加一个新的 Post 类

 1     public class Post
 2     {
 3         public int PostId { get; set; }
 4         [MaxLength(200)]
 5         public string Title { get; set; }
 6         public string Content { get; set; }
 7 
 8         public int BlogId { get; set; }
 9         public Blog Blog { get; set; }
10     }

在 Blog 类中添加 Posts 集合,来建立 Blog 和 Post 之间的关系

public virtual List<Post> Posts { get; set; }

执行命令 Add-Migration AddPostClass

但是,我们可能需要做一些改变:

1、为 Posts.Title 列添加唯一索引 (如代码22和29行所示)

2、添加一个不为空的 Blogs.Rating 列 (如代码24行所示设置默认值)

 1     namespace MigrationsDemo.Migrations
 2     {
 3         using System;
 4         using System.Data.Entity.Migrations;
 5         
 6         public partial class AddPostClass : DbMigration
 7         {
 8             public override void Up()
 9             {
10                 CreateTable(
11                     "dbo.Posts",
12                     c => new
13                         {
14                             PostId = c.Int(nullable: false, identity: true),
15                             Title = c.String(maxLength: 200),
16                             Content = c.String(),
17                             BlogId = c.Int(nullable: false),
18                         })
19                     .PrimaryKey(t => t.PostId)
20                     .ForeignKey("dbo.Blogs", t => t.BlogId, cascadeDelete: true)
21                     .Index(t => t.BlogId)
22                     .Index(p => p.Title, unique: true);
23 
24                 AddColumn("dbo.Blogs", "Rating", c => c.Int(nullable: false, defaultValue: 3));
25             }
26             
27             public override void Down()
28             {
29                 DropIndex("dbo.Posts", new[] { "Title" });
30                 DropIndex("dbo.Posts", new[] { "BlogId" });
31                 DropForeignKey("dbo.Posts", "BlogId", "dbo.Blogs");
32                 DropColumn("dbo.Blogs", "Rating");
33                 DropTable("dbo.Posts");
34             }
35         }
36     }

现在,迁移已编辑好,执行命令 Update-Database  –Verbose 

PS:加上 –Verbose 可查看 Code First Migrations 运行的SQL 

 

五、数据移动/定制SQL

添加 Post.Abstract 属性,稍后将从 Content 列中获取数据赋给 Abstract 

public string Abstract { get; set; }

执行命令 Add-Migration

将每一个post中的content 的前100个字符赋给Abstract (如第12行代码所示)

 1     namespace MigrationsDemo.Migrations
 2     {
 3         using System;
 4         using System.Data.Entity.Migrations;
 5         
 6         public partial class AddPostAbstract : DbMigration
 7         {
 8             public override void Up()
 9             {
10                 AddColumn("dbo.Posts", "Abstract", c => c.String());
11 
12                 Sql("UPDATE dbo.Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL");
13             }
14             
15             public override void Down()
16             {
17                 DropColumn("dbo.Posts", "Abstract");
18             }
19         }
20     }

执行命令 Update-Database  –Verbose 

 

六、迁移到特定版本(包括降级)

假设需要把数据库状态还原到运行AddBlogUrl 迁移之后,可以用TargetMigration

运行 Update-Database –TargetMigration: AddBlogUrl 

这个命令将运行 AddBlogAbstract 和 AddPostClass 的 Down script

如果要一路回滚到空数据库,则可执行 Update-Database –TargetMigration: $InitialDatabase

 

七、获取 SQL 脚本

 

Entity Framework Code First Migrations 官方Demo