在開發數據庫應用程序的時候,經常會遇到某些表需要添加字段或者修改類型、新增表等需求,而對於EF Code First來說關注的只有實體類,當需求變更時只需要添加新的實體類或者在實體類中添加、刪除、修改屬性即可。但是修改完成之后要如何將修改同步到數據庫中?
Entity Framework提供了Migrations機制來解決這一問題。
本文要點:
●啟用Migrations
●通過Add-Migration添加Migration
●Update-Database更新數據庫
●更新模型並添加新的Migration
●啟動應用時自動將數據庫更新至最新版本
●關於Automatic Migrations(自動遷移)
啟用Migrations
在VS中的Package Manager Console窗口中選擇默認項目為DbContext存在的項目,並執行命令:
enable-migrations
然后項目中將生成Migrations目錄和Configuration類型:
構造方法:用於對一些Migrations相關的配置,如上代碼就是禁用了自動遷移。
Seed方法:根據注釋可知在遷移后執行,一般用來添加默認數據。Configuration類型可以根據需求進行修改。
注:如過出現以下錯誤,可把命名空間刪除修復:
通過Add-Migration添加Migration
如果已經存在數據庫那么需要使用–IgnoreChanges參數來創建一個空的Migration來對應當前的數據庫模型:
Add-Migration InitialCreate –IgnoreChanges
這時在Migrations目錄下會生成一個帶時間戳的InitialCreate.cs文件:
注:上面的代碼的Up和Down方法之所以為空是因為使用了–IgnoreChanges參數,因為數據庫中已經有對應的表和字段,所以不應該再創建一次,如果去掉該參數會生成以下代碼:
Update-Database更新數據庫
執行Update-Database目錄來更新數據庫:
update-database -StartUpProjectName 'My Blog' -ProjectName BlogRepository.MySQL
注:由於本例的DbContext相關類型在BlogRepository.MySQL中,但是連接字符串在My Blog項目中,所以在執行數據庫更新時需要指定啟動項目和項目名稱兩個參數。一般情況下使用update-database命令即可。
這時數據庫中多了一個名稱為__MigrationsHistory表並有一條記錄。
更新模型並添加新的Migration
1. 為模型添加一個新的屬性"IsPublish"來代表文章是否被公開:
2. 運行Add-Migration命令,名稱最好與變更相關用於區分多個Migration便於維護:
add-migration addIsPublishColumn
執行命令后會生成一個DbMigration的子類,該類型中包含一個Up和Down方法,分別對應更新時和回退時對數據庫的操作:
上面的Up方法就是為dbo.Posts表添加名為"IsPublish"的列,如果回滾這個Migration時則把該列刪除。
3. 再次使用update-database命令將新的變更同步到數據庫中:
update-database -StartUpProjectName 'My Blog' -ProjectName BlogRepository.MySQL -Verbose
注:使用參數-Verbose可以看到更多執行信息,包括執行的SQL語句。
啟動應用時自動將數據庫更新至最新
啟動應用時將數據庫更新至最新可以省略“update-database”命令執行這一過程,只需要添加了Migration,並且該Migration沒有同步到數據庫,那么在應用執行(實際上是DbContext在創建模型時OnModelCreating)將會把修改同步到數據庫。
1. 添加ClickCount屬性:
2. 在DBContext類型中添加OnModelCreating方法及代碼(注:該操作也可以通過配置文件配置):
3. 運行程序:
4. 查看結果:
關於Automatic Migrations(自動遷移)
自動遷移指的是在執行“update-database”命令時,將對比實體模型與數據庫結構,如果它們有差異則以實體模型為准,將差異同步到數據庫。相當於省略了add-migration命令。
在執行啟動遷移命令(enable-migrations )時,可以添加參數–EnableAutomaticMigrations或者在生成待Configuration類型的構造方法中將AutomaticMigrationsEnabled的值設為true。
自動更新數據庫(migrate database to latest version)與自動遷移(automatic migrations),前者省略“update-database”后者省略“add-migration”,如果一起使用則兩者都省略,開發者僅需通過enable-migrations命令開啟遷移,然后在開發中修改完成實體類,就可以調試程序,調試程序過程中自動更新數據庫結構。
小結:
本章主要是介紹EF的遷移功能,對於EF來說這是一個非常重要的功能,因為在開發過程中特別是code first開發過程中,經常會添加實體、修改實體屬性甚至會在使用Fluent API來映射數據庫關系的時候也會針對某些屬性進行修改,如字段類型、最大長度以及索引等。
對於自動更新數據庫以及自動遷移功能,個人不建議在團隊開發正式項目時使用,因為使用Add-Migration命令可以很好的追蹤數據庫結構的更新,並且可以根據情況進行回滾。而自動更新數據庫會導致數據庫結構改變,團隊工作中如果多人使用了同一個數據庫並且在代碼未同步時會導致錯誤的出現。
但啟用自動遷移並且設置數據庫初始化時自動將數據庫更新至最新將節省很多操作。各有利弊可根據情況選擇。
參考:
https://msdn.microsoft.com/en-us/library/jj591621(v=vs.113).aspx
https://coding.abel.nu/2012/03/ef-migrations-command-reference/#Update-Database