标签:
https://msdn.microsoft.com/zh-cn/data/jj591621
Data Access and Storage > 学习 > Entity Framework > 开始操作 > Code First 迁移
本演练将提供对实体框架中 Code First 迁移的概述。您可以完成整个演练,也可以跳至自己感兴趣的主题。主题如下:
在我们开始使用迁移之前,需要有一个项目和一个 Code First 模型。对于本次演练任务,我们仍将使用 Blog 和 Post 规范模型。
using System.Data.Entity;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity.Infrastructure;
namespace MigrationsDemo
{
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
}
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MigrationsDemo
{
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);
}
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
}
现在要对我们的模型进行一些更改。
public string Url { get; set; }
如果您打算再次运行该应用程序,则将显示 InvalidOperationException,表明支持“BlogContext”上下文的模型已在数据库创建后发生更改。请考虑使用 Code First 迁移更新数据库 ( http://go.microsoft.com/fwlink/?LinkId=238269)。
按异常消息指示,现在应该开始使用 Code First 迁移。第一步是为上下文启用迁移。
此命令已为项目添加了 Migrations 文件夹,此新文件夹包含两个文件:
Code First 迁移有两个主命令,下面您将会熟悉它们。
我们需要为迁移搭建基架以处理先前添加的新 Url 属性。使用 Add-Migration 命令可以为这些迁移指定名称,我们将其称为 AddBlogUrl。
namespace MigrationsDemo.Migrations
{
using System;
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");
}
}
}
现在,我们可以编辑此迁移或向其添加内容,一切都很不错。让我们使用 Update-Database 将此迁移应用于数据库。
此时,MigrationsDemo.BlogContext 数据库已进行了更新,其 Blogs 表中包含了 Url 列。
到目前为止,我们生成并运行了迁移,而未进行任何更改。现在,让我们看一下如何编辑默认情况下生成的代码。
public int Rating { 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; }
}
public virtual List<Post> Posts { get; set; }
我们将使用 Add-Migration 命令让 Code First 迁移自动在迁移时为其最佳猜测搭建基架。我们将此迁移称为 AddPostClass。
Code First 迁移为这些更改搭建基架的工作做得很好,但有些内容可能需要我们更改:
namespace MigrationsCodeDemo.Migrations
{
using System;
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[] { "Title" });
DropIndex("Posts", new[] { "BlogId" });
DropForeignKey("Posts", "BlogId", "Blogs");
DropColumn("Blogs", "Rating");
DropTable("Posts");
}
}
}
我们编辑好的迁移已准备就绪,让我们使用 Update-Database 更新数据库。这次指定 –Verbose 标记,以便您能够看见 Code First 迁移所运行的 SQL。
到目前为止,我们了解了不更改或迁移任何数据的迁移操作,现在看一下需要来回移动一些数据的迁移操作。目前还没有为数据移动提供本机支持,但我们可以在脚本中的任何位置运行一些任意 SQL 命令。
public string Abstract { get; set; }
我们将使用 Add-Migration 命令让 Code First 迁移自动在迁移时为其最佳猜测搭建基架。
namespace MigrationsCodeDemo.Migrations
{
using System;
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");
}
}
}
我们编辑好的迁移很不错,让我们使用 Update-Database 更新数据库。我们将指定 –Verbose 标记,以便可以查看正在对数据库运行的 SQL。
到目前为止,我们一直是升级到最新迁移,但有时您可能需要升级/降级到特定迁移。
假如我们希望将数据库迁移到当时运行 AddBlogUrl 迁移后所处的状态。可以使用 –TargetMigration 开关降级到此迁移。
此命令将为 AddBlogAbstract 和 AddPostClass 迁移运行 Down 脚本。
如果要一直回滚到空数据库,可以使用 Update-Database –TargetMigration: $InitialDatabase 命令。
假如其他开发人员的计算机上也需要这些更改,则在我们将所做的更改签入源代码管理后,他们只需执行同步操作即可。在他们得到我们的新迁移后,即可运行 Update-Database 命令在本地应用这些更改。不过,如果希望将这些更改推送到测试服务器并最终应用于生产,我们可能希望向 DBA 提交一个 SQL 脚本。
Code First 迁移将运行迁移管道,而不是实际应用更改,它会自动将更改写出到一个 .sql 文件。生成脚本后,将会自动在 Visual Studio 中打开它,以供您查看或保存。
如果您要部署应用程序,可能希望在应用程序启动时自动升级数据库(通过应用所有挂起的迁移)。可通过注册 MigrateDatabaseToLatestVersion 数据库初始值设定项来实现这一点。数据库初始值设定项只是包含用于确保数据库安装正确的某种逻辑。首次在应用程序进程 (AppDomain) 中使用上下文时,将运行此逻辑。
我们可以更新 Program.cs 文件(如下所示),先设置 BlogContext 的 MigrateDatabaseToLatestVersion 初始值设定项,然后再使用上下文(第 14 行)。请注意,您还需要为 System.Data.Entity 命名空间添加一个 using 语句(第 5 行)。
创建此初始值设定项的实例时,需要指定上下文类型 (BlogContext) 和迁移配置 (Configuration) - 迁移配置是启用迁移时添加到 Migrations 文件夹的类。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using MigrationsDemo.Migrations;
namespace MigrationsDemo
{
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<BlogContext, Configuration>());
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);
}
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
}
现在,每次应用程序运行时,它都会先检查所面向的数据库是否是最新的;如果不是,便会应用所有挂起的迁移。
在本演练中,您了解到如何为基于代码的迁移搭建基架、编辑和运行这些迁移,从而实现数据库的升级和降级。此外,还了解到如何获取 SQL 脚本以将迁移应用于数据库,以及如何在应用程序启动时自动应用所有挂起的迁移。
标签:
原文地址:http://www.cnblogs.com/shiningrise/p/5628506.html