Code-First 建立資料庫初始值
前言
使用Code-First開發時,預設情況下會在第一次執行程式時建立DB,爾後如果有Model異動可利用Migration方式來同步資料庫結構,或者乾脆移除DB讓EF再次建立DB。在開發初期Model異動是家常便飯,因此是否可以在Model有異動時自動產生DB來取代舊的? 甚至直接建立預設資料來方便測試呢? 其實這些行為是可以依需求來調整的,以下說明。
資料庫初始方式
可以依照個人需求來選擇不同的資料庫初始方式。例如在開發初期,可能會選擇DropCreateDatabaseIfModelChanges來依據Model異動與否自動建立符合現況的DB;亦或者在開發後期需要對系統進行測試,希望每次執行都可以恢復DB至初始狀態時,就可以設定為DropCreateDatabaseAlways。以下介紹各差異性。
1. CreateDatabaseIfNotExists
預設規則,DB不存在時才建立,若Model與目前存在DB不相符會拋出例外錯誤
2. DropCreateDatabaseIfModelChanges
DB不存在時建立,若Model與目前存在DB不相符時會自動移除現有DB後再建立新DB
3. DropCreateDatabaseAlways
無論如何,總是移除現有DB(如果存在的話),再建立新DB
建立 Custom DB Initializer 賦予預設資料
最簡單的方式就是選定一種初始資料庫方式,接著建立Custom DB Initialier來繼承該資料庫初始化類別,並且複寫Seed方法來寫入預設資料於資料庫中。以下範例以DropCreateDatabaseIfModelChanges作為資料庫初始化方式,並且在資料庫初始時於SysRole資料表中建立2筆預設角色(Role)資料。
{
protected override void Seed(GekerDbContext context)
{
// Prepare initial roles
var sysRoles = new List<SysRole>()
{
new SysRole { Name = "PM", IsEnable = true },
new SysRole { Name = "Sales", IsEnable = true }
};
// Add roles in DB
context.SysRoles.AddRange(sysRoles);
context.SaveChanges();
}
}
設定 DB Initializer
最後告訴EF要以何種方式規則來初始資料庫。有兩種方式可以進行Initializer設定,以下介紹。
Set DB Initializer in DbContext Constructor
{
// Constructors
public GekerDbContext() : base("GekerDbContext")
{
// Initialize DB by Custom DB Initializer
Database.SetInitializer<GekerDbContext>(new GekerDbInitializer());
}
// Properties
public DbSet<SysRole> SysRoles { get; set; }
}
Set DB Initializer in Web.config
<!-- set database initializer -->
<contexts>
<!-- Geker.DataAccess.GekerDbContext is dbContext class -->
<!-- In Geker.DataAccess dll -->
<context type="Geker.DataAccess.GekerDbContext, Geker.DataAccess">
<!-- Geker.DataAccess.GekerDbInitializer is initializer class -->
<!-- In Geker.DataAccess dll -->
<databaseInitializer type="Geker.DataAccess.GekerDbInitializer, Geker.DataAccess" />
</context>
</contexts>
</entityFramework>
執行結果
在資料庫被初始化後,會執行Initilizer中Seed方法來建立2筆預設角色資料。
參考資訊
希望此篇文章可以幫助到需要的人
若內容有誤或有其他建議請不吝留言給筆者喔 !