.NET 6 如何在 program.cs 中自動執行遷移
在 .Net 5 中,我們過去可以通過將 DataContext 傳遞給 Configure 方法來呼叫遷移,並在啟動類中呼叫遷移。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DataContext dataContext) { // migrate any database changes on startup (includes initial db creation) dataContext.Database.Migrate(); ... }我們如何在 .Net 6 中做到這一點?
精簡版
聽起來真正的問題是把過去的程式碼放在哪裡
Startup.Configure。
Program.cs使用中using (var scope = app.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService<SomeDbContext>(); db.Database.Migrate(); }比較長的解釋
EF Core Migrations 文件中的Applying Migrations at Runtime部分顯示,就 EF Core 而言,沒有任何變化。
public static void Main(string[] args) { var host = CreateHostBuilder(args).Build(); using (var scope = host.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService<SomeDbContext>(); //Same as the question db.Database.Migrate(); } host.Run(); }聽起來真正的問題是把過去的程式碼放在哪裡
Startup.Configure。該程式碼可以放在Main方法中,或者,如果使用 Minimal API,則放在Program.cs.Configuration,Services等Environment可用作WebApplicationBuilder類或由它創建的WebApplication中的屬性。WebApplicationBuilder包含 DI、配置、日誌記錄和主機的建構器介面,例如WebApplicationBuilder.Services暴露IServiceCollection。
WebApplication屬性暴露由 配置的中間件WebApplicationBuilder,例如WebApplication.Services暴露IServiceProviderMinimal API 中的啟動替換
Startup.cs.NET 6中合併了其中的方法Program.cs。 Startup.cs 包含兩種方法:
- 配置主機和應用程序的方法,例如設置配置和 DI,通過呼叫各種建構器介面
IServiceCollection,如IConfigurationBuilder. 這包括以前在Startup.ConfigureServices.- 使用主機配置端點、使用服務和中間件的方法。這包括
Startup.Configure.在 .NET 6 中,介面移至 WebApplicationBuilder 和 WebApplication 類。代替 .NET Core 呼叫“神奇”的 Startup 類並註入介面,其中的程式碼
Program.cs可以直接訪問它需要的介面。
- 主機建構/配置服務現在可通過WebApplicationBuilder類獲得。
- 完整的應用程序宿主提供的介面現在可以通過WebApplicationBuilder建構的WebApplication類使用。
如果你不需要配置服務,你可以只用 3 行創建一個最小的 API 應用程序:
var app = WebApplication.Create(args); app.MapGet("/", () => "Hello World!"); app.Run();在您的情況下,您至少需要配置 DbContext,因此您需要單獨使用
WebApplicationBuilder和WebApplication。這將在下一節中顯示最小 API 中的遷移
在基本的最小 API 中
Program.cs:var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.Run();
WebApplication一旦通過其Services屬性創建實例,就可以創建 DbContexts :var builder = WebApplication.CreateBuilder(args); //Register the DbContexts etc. ... builder.Services.AddDbContext<SomeDbContext>(....); var app = builder.Build(); using (var scope = app.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService<SomeDbContext>(); db.Database.Migrate(); } app.MapGet("/", () => "Hello World!"); app.Run();當然,為這樣的程式碼使用單獨的方法或類要好得多,保持
Program.cs乾淨:var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext<SomeDbContext>(....); var app = builder.Build(); ApplyMigrations(app); app.MapGet("/", () => "Hello World!"); app.Run(); static void ApplyMigrations(WebApplication app) { using var scope = app.Services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService<SomeDbContext>(); db.Database.Migrate(); }甚至 :
var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext<SomeDbContext>(....); var app = builder.Build(); app.ApplyMigrations() .UseCustomLogging() .DoSomeOtherConfiguration() ...; app.MapGet("/", () => "Hello World!"); app.Run();在單獨的類中使用
ApplyMigrations擴展方法:public static DataExtensions { public static WebApplication ApplyMigrations(this WebApplication app) { using var scope = app.Services.CreateScope() var db = scope.ServiceProvider.GetRequiredService<SomeDbContext>(); db.Database.Migrate(); return app; } }