若是使用的是 Code First 工做流,推薦使用 Code First 遷移改進應用程序的數據庫架構。 遷移提供一組容許如下操做的工具:sql
下方演練將概述實體框架中的 Code First 遷移。 能夠完成整個演練或跳到感興趣的主題。 包含如下主題:數據庫
開始使用遷移以前,須要會用到項目和 Code First 模型。 對於此演練,咱們將使用規範的「博客」和「帖子」模型。服務器
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(); } } }
運行應用程序,隨即會建立 MigrationsCodeDemo.BlogContext 數據庫。架構
現可對模型進行更多更改。app
public string Url { get; set; }
若是要再次運行應用程序,則會收到一個 InvalidOperationException,指出「建立數據庫後,支持‘BlogContext’上下文的模型已發生變化。請考慮使用 Code First 遷移更新數據庫 (http://go.microsoft.com/fwlink/?LinkId=238269)」。框架
如異常狀況所述,可開始使用 Code First 遷移。 第一步是啓用上下文遷移。ide
在包管理器控制檯中運行 Enable-Migrations 命令工具
此命令已將「遷移」文件夾添加到項目中。 此新文件夾包含兩個文件:測試
配置類。 此類容許配置遷移對上下文的行爲方式。 對於此演練,將只使用默認配置。 因爲項目中只有一個 Code First 上下文,所以 Enable-Migrations 已自動填充此配置適用的上下文類型。ui
InitialCreate 遷移。 之因此生成此遷移,是由於在啓用遷移以前,咱們已使用 Code First 建立了數據庫。 已構建的遷移中的代碼表示已在數據庫中建立的對象。 在本演練中,即爲具備 BlogId 和「名稱」列的 Blog 表。 文件名包含時間戳,這樣有助於排序。若是還沒有建立數據庫,則不會將此 InitialCreate 遷移添加到項目中。相反,第一次調用 Add-Migration 時,會將建立這些表的代碼構建到新的遷移中。
使用 EF6 以前的版本時,只能使用一個 Code First 模型生成/管理數據庫的架構。 這是由於每一個數據庫的單個 __MigrationsHistory 表沒法識別哪些項屬於哪一個模型。
從 EF6 開始,配置類中包括 ContextKey 屬性。 該屬性充當每一個 Code First 模型的惟一標識符。 __MigrationsHistory 表中相應的列容許來自多個模型的項共享表。 默認狀況下,此屬性設置爲上下文的徹底限定名稱。
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("dbo.Blogs", "Url", c => c.String()); } public override void Down() { DropColumn("dbo.Blogs", "Url"); } } }
現可編輯或添加到此遷移,但全部內容看起來都很合適。 使用 Update-Database 將此遷移應用到數據庫。
MigrationsDemo.BlogContext 數據庫現已更新,其中包含「博客」表中的 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 MigrationsDemo.Migrations { using System; using System.Data.Entity.Migrations; public partial class AddPostClass : DbMigration { public override void Up() { CreateTable( "dbo.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("dbo.Blogs", t => t.BlogId, cascadeDelete: true) .Index(t => t.BlogId) .Index(p => p.Title, unique: true); AddColumn("dbo.Blogs", "Rating", c => c.Int(nullable: false, defaultValue: 3)); } public override void Down() { DropIndex("dbo.Posts", new[] { "Title" }); DropIndex("dbo.Posts", new[] { "BlogId" }); DropForeignKey("dbo.Posts", "BlogId", "dbo.Blogs"); DropColumn("dbo.Blogs", "Rating"); DropTable("dbo.Posts"); } } }
已編輯的遷移準備就緒,因此咱們使用 Update-Database 來更新數據庫。 此次指定 –Verbose 標誌,以即可以看到 Code First 遷移正在運行的 SQL。
到目前爲止,咱們已經介紹了不更改或移動任何數據的遷移操做,如今來看看須要移動數據的操做。 目前尚未對數據移動的原生支持,但咱們能夠在腳本中的任何位置運行一些任意 SQL 命令。
namespace MigrationsDemo.Migrations { using System; using System.Data.Entity.Migrations; public partial class AddPostAbstract : DbMigration { public override void Up() { AddColumn("dbo.Posts", "Abstract", c => c.String()); Sql("UPDATE dbo.Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL"); } public override void Down() { DropColumn("dbo.Posts", "Abstract"); } } }
已編輯的遷移一切正常,因此咱們可以使用 Update-Database 來更新數據庫。 咱們將指定 –Verbose 標誌,以即可以看到針對數據庫運行的 SQL。
到目前爲止,咱們一直在升級到最新遷移,但用戶有時可能但願升級/降級到特定遷移。
假設想在運行 AddBlogUrl 遷移後將數據庫遷移到其以前的狀態。 此時可以使用 –TargetMigration 切換爲降級到此遷移。
此命令將爲 AddBlogAbstract 和 AddPostClass 遷移運行 Down 腳本。
若是想要一直回退到空數據庫,可以使用 Update-Database –TargetMigration: $InitialDatabase 命令。
若是另外一位開發人員但願在其計算機上進行這些更改,則只需在咱們將更改簽入源代碼管理以後進行同步便可。 在得到咱們的新遷移後,他們只需運行 Update-database 命令便可在本地應用更改。 可是,若是想將這些更改推送到測試服務器以及最終的產品,則可能須要一個能夠傳遞給 DBA 的 SQL 腳本。
Code First 遷移將運行遷移管道,但並不是是應用更改,而是將更改寫入到 .sql 文件。 生成腳本後,將在 Visual Studio 中打開,以供查看或保存。
從 EF6 開始,若是指定 –SourceMigration $InitialDatabase,則生成的腳本將爲「冪等」。 冪等腳本能夠將當前任何版本的數據庫升級到最新版本(或使用 – TargetMigration 升級到指定版本)。 生成的腳本包括檢查 __MigrationsHistory 表的邏輯,而且僅應用之前未應用的更改。
若是要部署應用程序,則可能但願應用程序在啓動時自動升級數據庫(經過應用各類掛起的遷移)。 能夠經過註冊 MigrateDatabaseToLatestVersion 數據庫初始值設定項來執行此操做。 數據庫初始值設定項僅包含一些用於確保正確設置數據庫的邏輯。 第一次在應用程序進程中使用上下文時,會運行此邏輯 (AppDomain)。
以下所示,能夠更新 Program.cs 文件,以在使用上下文(第 14 行)以前,爲 BlogContext 設置 MigrateDatabaseToLatestVersion 初始化值設定項。 請注意,還須要爲 System.Data.Entity 命名空間(第 5 行)添加 using 語句。
建立此初始值設定項的實例時,須要指定上下文類型 (BlogContext) 和遷移配置(配置)- 遷移配置是啓用遷移時添加到「遷移」文件夾的類**。
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(); } } }
如今,每當應用程序運行時,它首先會檢查其目標數據庫是否爲最新,若是不是,則會應用各類掛起的遷移。
from: https://docs.microsoft.com/zh-cn/ef/ef6/modeling/code-first/migrations/
有用的URl :https://blog.csdn.net/zzulishulei/article/details/76685915