好久沒有在博客園更新博客了,如今都換了新公司。前段時間寫了關於EF遷移的文檔,今天拿出來作為這個系列的一篇吧。
一、Entity Framework 遷移命令(get-help EntityFramework)
Enable-Migrations 啟用遷移
Add-Migration 為掛起的Model變化添加遷移腳本
Update-Database 將掛起的遷移更新到數據庫
Get-Migrations 獲取已經應用的遷移
二、自定義遷移
現有一個Demo,有如下Product模型:
1: public class Product
2: {
3:
4: public int ProductId { get; set; }
5:
6: public string ProductName { get; set; }
7:
8: public decimal Price { get; set; }
9:
10: }
修改Product,添加如下兩個屬性:
1: public DateTime CreateDate { get; set; }
2:
3: public string Unit { get; set; }
其中,CreateDate和Unit都是必須的。
1. Enable-Migrations
在Package Manager Console中執行Enable-Migrations啟動遷移。
執行get-help Enable-Migrations –detailed 查看Enable-Migrations的詳細用法。
-ContextTypeName 指定要使用的Context
-EnableAutomaticMigrations 啟動自動遷移
-ProjectName 指定搭建的遷移類添加到的項目
-StartUpProjectName 指定使用的配置文件所在的項目
-ConnectionStringName 指定使用配置文件中連接字符串的名稱
-ConnectionString 指定使用的連接字符串
-ConnectionProviderName 指定連接字符串的provider名稱
-Force 重寫遷移配置
本Demo中執行
Enable-Migrations -ProjectName Demo.Domain -StartUpProjectName MigrationsDemo
執行結果是:檢測到數據庫是由database initializer創建,為現有的數據庫搭建初始化遷移腳本。本Demo中是在Demo.Domain項目中創建了一個Migrations文件夾,以及Migrations中的2個文件:Configuration.cs和201311010641361_InitialCreate.cs
Configuration 類。此類允許您針對上下文配置遷移的行為。
InitialCreate 遷移。此遷移已在啟用遷移之前生成,因為我們事先讓 Code First 自動創建了一個數據庫。此基架遷移中的代碼表示數據庫中已創建的對象。
如果尚未創建數據庫,則不會將此 InitialCreate 遷移添加到項目中。而是,首次調用 Add-Migration 時,用於創建這些表的代碼將為新遷移搭建基架。
2. Add-Migration
在Package Manager Console中執行Add-Migration搭建掛起的Model變化遷移腳本。
執行get-help Add-Migration –detailed查看Add-Migration的詳細用法。
-Name 指定自定義腳本的名稱
-Force
-ProjectName
-StartUpProjectName
-ConfigurationTypeName 指定使用的遷移配置
-IgnoreChanges 忽略檢測到掛起的model改變,創建一個空的遷移。這個選項可用來為已有的數據庫啟用遷移創建一個初始的,空的遷移。
-ConnectionStringName 指定使用配置文件中連接字符串的名稱
-ConnectionString 指定使用的連接字符串
-ConnectionProviderName 指定連接字符串的provider名稱
本Demo中執行
Add-Migration Add_Product_CreateDateAndUnit -ProjectName Demo.Domain
生成的Add_Product_CreateDateAndUnit:
2.1 SQL方法
前面提到CreateDate和Unit都是必須的,像Unit是string類型的,更新到數據庫默認值為空,CreateDate默認值為1900/1/1 0:00:00,如下圖
如果需要更改CreateDate或Unit的值,可以在Up()中使用Sql方法:
注:更新腳本時,將Unit設為中文,記得加’N’,否則在LocalDB中更新的內容會變成’?’,在SQL Server 2008 R2中沒有,無論用什么數據庫加上都是一個好習慣!
2.2 IgnoreChanges的使用
如果要映射現有的數據庫,可以執行Add-Migration Initial,然后執行 Update-Database
這樣就創建了一個初始的遷移。在這個基礎上再修改Demo,然后遷移。
3. Update-Database
在Package Manager Console中執行Update-Database將掛起的遷移更新到數據庫。
執行get-help Update-Database -detailed查看Add-Migration的詳細用法。
-SourceMigration 只有-Script打開時才有效。指定遷移的名稱用作更新的起點。忽略則使用最后一次應用的遷移。
-TargetMigration 指定將數據庫更新到哪個遷移的名稱。
-Script 生成SQL腳本
-Force
-ProjectName
-StartProjectName
- ConfigurationTypeName
-ConnectionStringName 指定使用配置文件中連接字符串的名稱
-ConnectionString 指定使用的連接字符串
-ConnectionProviderName 指定連接字符串的provider名稱
本Demo中執行
Update-Database -ProjectName Demo.Domain
3.1 遷移到特定版本
上面提到可以使用-TargetMigration開關將數據庫遷移到特定的狀態。比如,撤銷數據庫新添加的CreateDate和Unit字段。執行
Update-Database -ProjectName Demo.Domain -TargetMigration:InitialCreate
如果要一直回滾到空數據庫,可以使用 Update-Database –TargetMigration:0或-TargetMigration:$InitialDatabase命令。
3.2 生成SQL腳本
生成SQL腳本要使用-Script開關,另外兩個比較重要的開關是:-SourceMigration和-TargetMigration。
比如我們要生成InitialCreate到 Add_Product_CreateDateAndUnit的遷移SQL腳本,則執行如下命令:
Update-Database -ProjectName Demo.Domain -Script -SourceMigration:InitialCreate -TargetMigration:Add_Product_CreateDateAndUnit
生成下面的SQL腳本
如果忽略-SourceMigration開關,則使用最后一次應用的遷移作為起點,忽略-TargetMigration,則使用最新遷移作為終點。
4. 應用程序啟動時自動升級
通過注冊 MigrateDatabaseToLatestVersion 數據庫初始值設定項來實現該功能。數據庫初始值設定項只是包含用於確保數據庫安裝正確的某種邏輯。首次在應用程序進程 (AppDomain) 中使用上下文時,將運行此邏輯。
Demo中執行
Database.SetInitializer(new MigrateDatabaseToLatestVersion<OrderContext, Configuration>());
其中Configuration生成的是internal sealed class,不在一個程序集中需要修改成public
三、使用Migrate.exe遷移
將命令行工具migrate.exe復制到包含遷移配置的程序集位置,可以在VS外部進行遷移操作。
在使用 NuGet 安裝實體框架時,migrate.exe 位於下載包的 tools 文件夾中。在 <項目文件夾>\packages\EntityFramework.<版本>\tools 中
有了 migrate.exe 之后,需要將其復制到包含遷移的程序集位置。
如果應用程序面向 .NET 4 而不是 4.5,則還需要將 Redirect.config 復制到這個位置,並將其重命名為 migrate.exe.config。這樣,migrate.exe 會讓正確的綁定重定向能夠找到實體框架程序集。
注意:migrate.exe 目前不支持 x64 程序集。
Migrate.exe的使用
migrate.exe /? 顯示幫助信息
migrate assembly [configurationType] [/targetMigration]
[/startUpDirectory] [/startUpConfigurationFile]
[/startUpDataDirectory] [/connectionStringName]
[/connectionString] [/connectionProviderName] [/force] [/verbose]
[/?]
Assembly 指定包含遷移配置類型的程序集
[configurationType] 指定遷移配置類型的名稱
[connectionProviderName] 指定連接字符的provider
[connectionString] 指定使用的連接字符串
[connectionStringName] 指定配置文件中使用的連接字符串名稱
[force] 表示允許自動遷移引起數據丟失
[startUpConfigurationFile] 指定程序的Web.config或App.config
[startUpDataDirectory] 指定當解析包含|DataDirectory|的連接字符串時使用的目錄
[targetMigration] 指定遷移到的版本
[verbose] 指定輸出執行的SQL和其他信息到控制台
本Demo中執行
migrate Demo.Domain.dll /startUpConfigurationFile="MigrationsDemo.exe.config" /targetMigration=” Add_Product_CreateDateAndUnit” /verbose