套用移轉

一旦新增移轉,就必須部署並套用至資料庫。 有各種策略可以這麼做,有些更適合生產環境,有些則適用于開發生命週期。

注意

無論您的部署策略為何,一律檢查產生的移轉,並在套用至生產資料庫之前進行測試。 移轉可能會在意圖重新命名資料行時卸載資料行,或可能會因為套用至資料庫的各種原因而失敗。

SQL 指令碼

將移轉部署至生產資料庫的建議方式是產生 SQL 腳本。 此策略的優點包括:

  • 您可以檢閱 SQL 腳本以取得正確性;這很重要,因為將架構變更套用至生產資料庫是可能涉及資料遺失的潛在危險作業。
  • 在某些情況下,腳本可以調整以符合生產資料庫的特定需求。
  • SQL 腳本可以與部署技術搭配使用,甚至可以在 CI 程式中產生。
  • SQL 腳本可以提供給 DBA,而且可以分開管理和封存。

基本使用方式

下列作業會從空白資料庫產生 SQL 腳本到最新的移轉:

dotnet ef migrations script

使用 From (隱含)

下列作業會產生從指定移轉至最新移轉的 SQL 腳本。

dotnet ef migrations script AddNewTables

使用 From 與 To

下列作業會產生從指定的移轉到指定 fromto 移轉的 SQL 腳本。

dotnet ef migrations script AddNewTables AddAuditTable

您可以使用比 to 新的 from 來產生復原指令碼。

警告

請注意,可能會發生資料遺失的狀況。

腳本產生會接受下列兩個引數,以指出應該產生哪一個移轉範圍:

  • 執行指令碼之前,from 移轉應該是套用到資料庫的最後一個移轉。 若未套用任何移轉,請指定 0 (此為預設)。
  • 執行指令碼之後,to 移轉是套用到資料庫的最後一個移轉。 預設為您專案中的最後一個移轉。

等冪 SQL 腳本

上述產生的 SQL 腳本只能套用,以將架構從一個移轉變更為另一個移轉;您必須負責適當地套用腳本,並且只套用至處於正確移轉狀態的資料庫。 EF Core 也支援產生 等冪 腳本,這些腳本會在內部檢查哪些移轉已透過移轉歷程記錄資料表 () 套用哪些移轉,並僅套用遺漏的腳本。 如果您不知道最後一個移轉套用至資料庫的內容,或者您要部署至可能位於不同移轉的多個資料庫,這會很有用。

下列會產生等冪移轉:

dotnet ef migrations script --idempotent

命令列工具

EF 命令列工具可用來將移轉套用至資料庫。 雖然對於本機開發和測試移轉具有生產力,但這種方法不適合用于管理生產資料庫:

  • SQL 命令會由工具直接套用,而不會讓開發人員有機會檢查或修改它們。 這在生產環境中可能很危險。
  • .NET SDK 和 EF 工具必須安裝在生產伺服器上,而且需要專案的原始程式碼。

下列會將您的資料庫更新為最新的移轉:

dotnet ef database update

下列作業會將資料庫更新為指定的移轉:

dotnet ef database update AddNewTables

請注意,這也可以用來復原到先前的移轉。

警告

請注意,可能會發生資料遺失的狀況。

如需透過命令列工具套用移轉的詳細資訊,請參閱 EF Core 工具參考

注意

這項功能是在 EF Core 6.0 中引進。

移轉配套是單一檔案可執行檔,可用來將移轉套用至資料庫。 它們解決了 SQL 腳本和命令列工具的一些缺點:

  • 執行 SQL 腳本需要其他工具。
  • 這些工具的交易處理和繼續錯誤行為不一致,有時不一致。 如果套用移轉時發生失敗,這可能會讓您的資料庫處於未定義的狀態。
  • 套件組合可以產生為 CI 程式的一部分,並在部署程式稍後輕鬆地執行。
  • 套件組合可以在不需要安裝 .NET SDK 或 EF Tool (或甚至是 .NET 執行時間的情況下執行,而獨立式) ,而且不需要專案的原始程式碼。

下列會產生套件組合:

dotnet ef migrations bundle

下列專案會產生適用于 Linux 的獨立套件組合:

dotnet ef migrations bundle --self-contained -r linux-x64

如需建立套件組合的詳細資訊,請參閱 EF Core 工具參考

efbundle

產生的可執行檔預設會命名 efbundle 。 它可以用來將資料庫更新為最新的移轉。 相當於執行 dotnet ef database updateUpdate-Database

引數:

引數 描述
<MIGRATION> 目標移轉。 如果為 '0',則會還原所有移轉。 預設為上次移轉。

選項:

選項 Short 描述
--connection <CONNECTION> 資料庫的連接字串。 預設為 AddDbCoNtext 或 OnConfiguring 中指定的 。
--verbose -v 顯示詳細資訊輸出。
--no-color 不要將輸出著色。
--prefix-output 具有層級的前置詞輸出。

下列範例會使用指定的使用者名稱和密碼,將移轉至本機SQL Server實例。

.\efbundle.exe --connection 'Data Source=(local)\MSSQLSERVER;Initial Catalog=Blogging;User ID=myUsername;Password=myPassword'

在執行階段套用移轉

應用程式本身可以程式設計方式套用移轉,通常是在啟動期間。 雖然對於本機開發和測試移轉具有生產力,但這種方法不適合管理生產資料庫,原因如下:

  • 如果應用程式的多個實例正在執行,這兩個應用程式可能會嘗試同時套用移轉,並失敗 (或更糟,導致資料損毀) 。
  • 同樣地,如果應用程式在另一個應用程式移轉資料庫時存取資料庫,這可能會導致嚴重問題。
  • 應用程式必須具有更高的存取權,才能修改資料庫架構。 通常最好限制應用程式在生產環境中的資料庫許可權。
  • 請務必在發生問題時復原套用的移轉。 其他策略可輕易且立即提供。
  • SQL 命令會由程式直接套用,而不會讓開發人員有機會檢查或修改它們。 這在生產環境中可能很危險。

若要以程式設計方式套用移轉,請呼叫 context.Database.Migrate() 。 例如,典型的 ASP.NET 應用程式可以執行下列動作:

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();

    using (var scope = host.Services.CreateScope())
    {
        var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
        db.Database.Migrate();
    }

    host.Run();
}

請注意, Migrate() 建置在服務之上 IMigrator ,可用於更進階的案例。 您可以使用 myDbContext.GetInfrastructure().GetService<IMigrator>() 來加以存取。

警告

  • 在生產環境中使用此方法之前,請先仔細考慮。 經驗顯示,此部署策略的簡單性超過其建立的問題。 請考慮改為從移轉產生 SQL 腳本。
  • 請勿在 Migrate() 之前呼叫 EnsureCreated()EnsureCreated() 會略過移轉而建立結構描述,因此造成 Migrate() 失敗。