咱們能夠在初始化數據庫的過程當中給數據庫添加一些數據。爲了實現初始化數據(seed data)咱們必須建立一個自定義的數據庫初始化器(DB initializer),並重寫其中的Seed方法。html
下邊的栗子展現在School數據庫中給Standard表添加默認的數據:數據庫
第一步:建立自定義初始化器ide
//繼承三種內置的初始化器中的DropCreateDatabaseAlways public class SchoolDBInitializer : DropCreateDatabaseAlways<SchoolDBContext> { protected override void Seed(SchoolDBContext context) { IList<Standard> defaultStandards = new List<Standard>(); defaultStandards.Add(new Standard() { StandardName = "Standard 1", Description = "First Standard" }); defaultStandards.Add(new Standard() { StandardName = "Standard 2", Description = "Second Standard" }); defaultStandards.Add(new Standard() { StandardName = "Standard 3", Description = "Third Standard" }); context.Standards.AddRange(defaultStandards); //初始化數據 base.Seed(context); } }
第二步.將自定義的數據庫初始化器添加到context中工具
public class SchoolContext: DbContext { public SchoolContext(): base("SchoolDB") { Database.SetInitializer(new SchoolDBInitializer()); } public DbSet<Student> Students { get; set; } public DbSet<Standard> Standards { get; set; } }
前邊咱們已經知道了EF中的數據庫遷移策略(CreateDatabaseIfNotExists,DropCreateDatabaseIfModelChanges, and DropCreateDatabaseAlways.),可是由於這些策略都是刪除舊的數據庫而後建立一個新的數據庫,因此使用這些策略會形成數據庫中的數據(不是seed data的數據)、存儲過程、觸發器等內容丟失。ui
針對上邊的問題,EF提供了一個新的數據庫初始化器 MigrateDatabaseToLastestVersion,這個工具在實體模型改變時自動幫咱們更新數據庫,且不會形成數據丟失。spa
下邊介紹兩種更新數據庫的方法:設計
第一步:3d
在程序包管理器控制檯輸入code
enable-migrations –EnableAutomaticMigration:$true
執行成功後,EFAp建立了一個繼承自DbMigrationConfiguration類的Configuration類,以下htm
internal sealed class Configuration : DbMigrationsConfiguration<EF6Demo.SchoolContext> { public Configuration() { AutomaticMigrationsEnabled = true;//自動遷移爲true AutomaticMigrationDataLossAllowed = true;//容許數據丟失,默認生成時沒有這一項(不添加這一項時,只在添加/刪除實體類時自動生成,若是咱們刪除了實體類的一個屬性就會拋出異常) ContextKey = "EF6Demo.SchoolContext"; } protected override void Seed(EF6Demo.SchoolContext 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. } }
第二步:
把數據庫初始化器添加到配置中,context代碼以下:
public class SchoolContext : DbContext { public SchoolContext() { //添加MigrateDatabaseToLatestVersion數據庫初始化器 Database.SetInitializer(new MigrateDatabaseToLatestVersion<SchoolContext, Configuration>()); } public virtual DbSet<Student> Students { get; set; } public virtual DbSet<Standard> Standards { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); } }
完成上邊兩步,當咱們修改實體類時運行程序就會自動更新數據庫。
上邊咱們瞭解了經過自動遷移來更新數據庫,這裏介紹經過代碼更新數據庫的方法。經過代碼更新數據庫的功能更強大,如咱們能夠給數據庫的列添加默認值,添加計算列等。
使用代碼遷移,咱們在程序包控制檯執行如下過程:
這條命令會生成一個Configuration文件,當配置文件存在時可經過-f後綴強制覆蓋舊文件。執行成功後添加了Migrations文件夾,文件夾中包含一個Configuration配置類,以下:
Configuration配置類代碼以下:
internal sealed class Configuration : DbMigrationsConfiguration<EF6Demo.SchoolContext> { public Configuration() { AutomaticMigrationsEnabled = false; ContextKey = "EF6Demo.SchoolContext"; } protected override void Seed(EF6Demo.SchoolContext 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. } }
首先在context類中指定初始化器是MigrateDatabaseToLatestVersion初始化器,以下:
public class SchoolContext : DbContext { public SchoolContext() { //添加MigrateDatabaseToLatestVersion數據庫初始化器 Database.SetInitializer(new MigrateDatabaseToLatestVersion<SchoolContext, Configuration>()); } public virtual DbSet<Student> Students { get; set; } public virtual DbSet<Standard> Standards { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); } }
在包管理器控制檯執行:
Add-Migration FirstInit
這會在Migration文件夾中生成一個<stamp>_name的遷移類:
遷移類的代碼以下:
public partial class FirstInit : DbMigration { //升級 public override void Up() { CreateTable( "dbo.Standards", c => new { StandardId = c.Int(nullable: false, identity: true), StandardName = c.String(), }) .PrimaryKey(t => t.StandardId); CreateTable( "dbo.Students", c => new { StudentId = c.Int(nullable: false, identity: true), StudentName = c.String(), Standard_StandardId = c.Int(), }) .PrimaryKey(t => t.StudentId) .ForeignKey("dbo.Standards", t => t.Standard_StandardId) .Index(t => t.Standard_StandardId); } //降級 public override void Down() { DropForeignKey("dbo.Students", "Standard_StandardId", "dbo.Standards"); DropIndex("dbo.Students", new[] { "Standard_StandardId" }); DropTable("dbo.Students"); DropTable("dbo.Standards"); } }
咱們能夠看到遷移類中包含Up()和Down()方法,分別用於數據庫的更新和回退。
① updata-database [-verbose]
在程序包控制檯中執行這條命令時,會執行Add-Migration命令建立的最新的遷移文件,並更新數據庫。
執行完上邊三步數據庫就生成了,之後當咱們修改實體類時,執行Add-Migration [MigName]後再執行Update-Database [-verbose],就可方便地根據模型的變化更新數據庫。
② update-database -TargetMigration:xxx
若是咱們想回退到某一個版本時執行:
update-database -TargetMigration:FirstInit//數據庫回退到第一次的版本
咱們知道codeFirst模式中不支持設計器,設計器對咱們理解實體間關係仍是頗有用的,怎麼在code-first中使用設計器呢?Visual Studio Marketplace.點擊連接下載工具,安裝便可,安裝完成重啓VS,在context上點擊右鍵,而後會有一個Entity Framework選項,以下圖:
點擊ViewEntity Data Model選項就能夠自動生成設計器,以下:
這個工具十分好用,同時也支持生成Model XML和DDL SQL推薦使用。