Wednesday, August 26, 2015

[Entity Framework 6] Code Frist (3) - Migration commands


.NET   Entity Framework   Code First   Database Migration  


▌背景

以Entity Framework Migration commands 來做建立或更新Code First資料庫的Snapshot。
可做DB Initialize及隨時還原,相當方便。



▌環境

l   Windows 7 pro
l   Visual Studio 2015 Ent.
l   MS Sql Server 2008 R2
l   Entity Framework 6


▌新增資料庫




▋Create Code-First DbContext and Models

可參考 Entity Framework Code Frist (1) 建立。


▋Enable Database Migrations

開啟「Nuget套件管理員→「套件管理器主控台」,輸入

Enable-Migrations

如果出現以下錯誤 …


=> 請將預設專案改為包含DbContext的專案!


成功後,會在專案下建立Migrations\Configuration.cs
稍後我們可以將DB Initialize的程式碼寫在這邊。




如果需要重新建立 Migrations\Configuration.cs
可下以下指令:

Enable-Migrations -Force



▋Create Initial migration snapshot

Add-Migration InitialCreate

此指令將建立一個第一版的Migration snapshot。



Update-Database

此指令將建立資料庫,且會在DB加上一筆Migration History資料。





▌更新資料庫



▋Add a new migration : 加入新表格並在現有資料表加上對應之Foreign Key

假設我們更新了Code-First資料庫如下:
l   新增兩個Mapping tables (Code tables)
l   在既有資料表加上兩個Foreign Key對應到上面的兩個表格

加入新的Migration~

Add-Migration NewTablesAndFKs




注意,在資料表裡面有資料的情況下,可能會違反FK的限制,此時必須手動Migration裡面的程式碼。



將有FK限制的欄位改為可允許NULL值 :



同時,也可以在Migrations\Configuration.cs 的 Seed() 方法裡,加上DB Initialize的程式碼。
例如:

protected override void Seed(JB.OWIN.Identity.Core.DbContext.AuthContext context)
        {
            //  This method will be called after migrating to the latest version.
            context.AspNetDepartments.AddOrUpdate(
                x=>x.Name,
                new AspNetDepartment() { Name = "應用一課" },
                new AspNetDepartment() { Name = "應用二課" },
                new AspNetDepartment() { Name = "應用三課" }
                );

            context.AspNetPositionLevels.AddOrUpdate(
               x=>x.Name,
                new AspNetPositionLevel() { Name = "助理工程師" },
                new AspNetPositionLevel() { Name = "工程師" },
                new AspNetPositionLevel() { Name = "資深工程師" },
                new AspNetPositionLevel() { Name = "主任工程師" });
        }




▋更新資料庫!

直接輸入

Update-Database

或指定Migration

Update-Database -TargetMigration NewTableAndFKs



▌Tips   

▋查詢已套用到資料庫的 migrations

Get-Migrations

輸出:
201508260325096_AddIndexTest4
201508260250358_NewTablesAndFKs
201508260242098_InitalCreate



▋還原至先前的Migration

Update-Database -TargetMigration [Migration Name]

當還原後,在建立新的Migration可能會出現以下錯誤訊息:

Unable to generate an explicit migration because the following explicit migrations are pending: [201508260311389_AddIndexTest1]. Apply the pending explicit migrations before attempting to generate a new explicit migration.

=>
解決方式:請先到方案總管刪除棄用的Migration。



▋未作實際Migration及Update之DbContext將導致錯誤

參考之錯誤訊息,解決方式:
l   建立Migrateion並Update資料庫
l   或是 將DbContext及Model的內容還原至與目前資料庫相同 (可能性較小)

The model backing the 'AuthContext' context has changed since the database was created. Consider using Code First Migrations to update the database


▋避免在Migrations\Configuration.cs Seed方法所產生的DB Initialize值為亂碼

請將Configuration.cs的編碼改為 UTF8 或 Unicode。
再執行一次 Update-Database.




▌Reference



No comments:

Post a Comment