1.添加初始化資料(Seed)
我們可以在初始化資料庫的過程中給資料庫添加一些資料。為了實作初始化資料(seed data)我們必須建立一個自定義的資料庫初始化器(DB initializer),并重寫其中的Seed方法。
下邊的栗子展示在School資料庫中給Standard表添加預設的資料:
第一步:建立自定義初始化器
//繼承三種内置的初始化器中的DropCreateDatabaseAlways
public class SchoolDBInitializer : DropCreateDatabaseAlways{protected override voidSeed(SchoolDBContext context)
{
IList defaultStandards = new List();
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 classSchoolContext: DbContext
{public SchoolContext(): base("SchoolDB")
{
Database.SetInitializer(newSchoolDBInitializer());
}public DbSet Students { get; set; }public DbSet Standards { get; set; }
}
2.資料庫遷移政策
前邊我們已經知道了EF中的資料庫遷移政策(CreateDatabaseIfNotExists,DropCreateDatabaseIfModelChanges, and DropCreateDatabaseAlways.),但是因為這些政策都是删除舊的資料庫然後建立一個新的資料庫,是以使用這些政策會造成資料庫中的資料(不是seed data的資料)、存儲過程、觸發器等内容丢失。
針對上邊的問題,EF提供了一個新的資料庫初始化器 MigrateDatabaseToLastestVersion,這個工具在實體模型改變時自動幫我們更新資料庫,且不會造成資料丢失。
下邊介紹兩種更新資料庫的方法:
1.自動遷移
第一步:
在程式包管理器控制台輸入
enable-migrations –EnableAutomaticMigration:$true
執行成功後,EFAp建立了一個繼承自DbMigrationConfiguration類的Configuration類,如下
internal sealed class Configuration : DbMigrationsConfiguration{publicConfiguration()
{
AutomaticMigrationsEnabled= true;//自動遷移為true
AutomaticMigrationDataLossAllowed = true;//允許資料丢失,預設生成時沒有這一項(不添加這一項時,隻在添加/删除實體類時自動生成,如果我們删除了實體類的一個屬性就會抛出異常)
ContextKey = "EF6Demo.SchoolContext";
}protected override voidSeed(EF6Demo.SchoolContext context)
{//This method will be called after migrating to the latest version.//You can use the DbSet.AddOrUpdate() helper extension method//to avoid creating duplicate seed data.
}
}
第二步:
把資料庫初始化器添加到配置中,context代碼如下:
public classSchoolContext : DbContext
{publicSchoolContext() {//添加MigrateDatabaseToLatestVersion資料庫初始化器
Database.SetInitializer(new MigrateDatabaseToLatestVersion());
}public virtual DbSet Students { get; set; }public virtual DbSet Standards { get; set; }protected override voidOnModelCreating(DbModelBuilder modelBuilder)
{base.OnModelCreating(modelBuilder);
}
}
完成上邊兩步,當我們修改實體類時運作程式就會自動更新資料庫。
2.使用代碼遷移
上邊我們了解了通過自動遷移來更新資料庫,這裡介紹通過代碼更新資料庫的方法。通過代碼更新資料庫的功能更強大,如我們可以給資料庫的列添加預設值,添加計算列等。
使用代碼遷移,我們在程式包控制台執行以下過程:
1.Enable-Migrations [-f]
這條指令會生成一個Configuration檔案,當配置檔案存在時可通過-f字尾強制覆寫舊檔案。執行成功後添加了Migrations檔案夾,檔案夾中包含一個Configuration配置類,如下:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SZlhjZ1gTMllTYhJ2YzETOlVGM4QGN4YDZ5EWOxUzYz8CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
Configuration配置類代碼如下:
internal sealed class Configuration : DbMigrationsConfiguration{publicConfiguration()
{
AutomaticMigrationsEnabled= false;
ContextKey= "EF6Demo.SchoolContext";
}protected override voidSeed(EF6Demo.SchoolContext context)
{//This method will be called after migrating to the latest version.//You can use the DbSet.AddOrUpdate() helper extension method//to avoid creating duplicate seed data.
}
}
2.Add-Migration [MigName]
首先在context類中指定初始化器是MigrateDatabaseToLatestVersion初始化器,如下:
public classSchoolContext : DbContext
{publicSchoolContext() {//添加MigrateDatabaseToLatestVersion資料庫初始化器
Database.SetInitializer(new MigrateDatabaseToLatestVersion());
}public virtual DbSet Students { get; set; }public virtual DbSet Standards { get; set; }protected override voidOnModelCreating(DbModelBuilder modelBuilder)
{base.OnModelCreating(modelBuilder);
}
}
在包管理器控制台執行:
Add-Migration FirstInit
這會在Migration檔案夾中生成一個_name的遷移類:
遷移類的代碼如下:
public partial classFirstInit : DbMigration
{//更新
public override voidUp()
{
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 voidDown()
{
DropForeignKey("dbo.Students", "Standard_StandardId", "dbo.Standards");
DropIndex("dbo.Students", new[] { "Standard_StandardId"});
DropTable("dbo.Students");
DropTable("dbo.Standards");
}
}
我們可以看到遷移類中包含Up()和Down()方法,分别用于資料庫的更新和回退。
3.Update-Database
① updata-database [-verbose]
在程式包控制台中執行這條指令時,會執行Add-Migration指令建立的最新的遷移檔案,并更新資料庫。
執行完上邊三步資料庫就生成了,以後當我們修改實體類時,執行Add-Migration [MigName]後再執行Update-Database [-verbose],就可友善地根據模型的變化更新資料庫。
② update-database -TargetMigration:xxx
如果我們想回退到某一個版本時執行:
update-database -TargetMigration:FirstInit//資料庫回退到第一次的版本
3.codeFirst中的設計器
我們知道codeFirst模式中不支援設計器,設計器對我們了解實體間關系還是很有用的,怎麼在code-first中使用設計器呢?Visual Studio Marketplace.點選連結下載下傳工具,安裝即可,安裝完成重新開機VS,在context上點選右鍵,然後會有一個Entity Framework選項,如下圖:
點選ViewEntity Data Model選項就可以自動生成設計器,如下:
這個工具十分好用,同時也支援生成Model XML和DDL SQL推薦使用。