【遷移】—Entity Framework例項詳解
好久沒有在部落格園更新部落格了,如今都換了新公司。前段時間寫了關於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