.NET 6 如何 运行 在 program.cs 中自动迁移
.NET 6 how to run Migration automatically in program.cs
在 .Net 5 中,我们过去可以通过将 DataContext 传递给 Configure 方法来调用迁移,并在启动时调用迁移 class。
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 迁移文档中的 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 APIs,则放在 Program.cs
中。 Configuration
、Services
、Environment
等可作为其创建的 WebApplicationBuilder class or the WebApplication 中的属性使用。 WebApplicationBuilder
包含用于 DI、配置、日志记录和主机的构建器接口,例如 WebApplicationBuilder.Services
公开 IServiceCollection
。
WebApplication
属性公开由 WebApplicationBuilder
配置的中间件,例如 WebApplication.Services
公开 IServiceProvider
以最小 APIs
启动替换
.NET 6 中 Startup.cs
中的方法已合并到 Program.cs
中。Startup.cs 包含两种方法:
- 通过调用
IServiceCollection
、IConfigurationBuilder
等各种构建器接口来配置主机和应用程序的方法,例如设置配置和 DI。这包括曾经在 Startup.ConfigureServices
. 中的代码
- 使用主机配置端点、使用服务和中间件的方法。这包括
Startup.Configure
. 中的代码
在 .NET 6 中,接口移动到 WebApplicationBuilder 和 WebApplication classes。 Program.cs
中的代码可以直接访问它需要的接口,而不是 .NET Core 调用“神奇的”Startup class 并注入接口。
- 主机 building/configuration 服务现在可以通过 WebApplicationBuilder class 获得。
- 完整的应用程序宿主提供的接口现在可以通过由 WebApplicationBuilder 构建的 WebApplication class 获得。
如果您不需要配置服务,您可以只用 3 行创建一个最小的 API 应用程序:
var app = WebApplication.Create(args);
app.MapGet("/", () => "Hello World!");
app.Run();
在您的情况下,您至少需要配置 DbContext,因此您需要分别使用 WebApplicationBuilder
和 WebApplication
。这将在下一节中显示
最小迁移 APIs
基本最小APIProgram.cs
:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
一旦通过 Services
属性:
创建了 WebApplication
实例,就可以创建 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();
当然 很多 更好地使用单独的方法或 classes 此类代码,保持 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
单独的扩展方法 class :
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;
}
}
在ASP.NET核心6中,应该是:
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<YourDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("YourConnectionString")));
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<YourDbContext>();
db.Database.Migrate();
}
在 .Net 5 中,我们过去可以通过将 DataContext 传递给 Configure 方法来调用迁移,并在启动时调用迁移 class。
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 迁移文档中的 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 APIs,则放在 Program.cs
中。 Configuration
、Services
、Environment
等可作为其创建的 WebApplicationBuilder class or the WebApplication 中的属性使用。 WebApplicationBuilder
包含用于 DI、配置、日志记录和主机的构建器接口,例如 WebApplicationBuilder.Services
公开 IServiceCollection
。
WebApplication
属性公开由 WebApplicationBuilder
配置的中间件,例如 WebApplication.Services
公开 IServiceProvider
以最小 APIs
启动替换.NET 6 中 Startup.cs
中的方法已合并到 Program.cs
中。Startup.cs 包含两种方法:
- 通过调用
IServiceCollection
、IConfigurationBuilder
等各种构建器接口来配置主机和应用程序的方法,例如设置配置和 DI。这包括曾经在Startup.ConfigureServices
. 中的代码
- 使用主机配置端点、使用服务和中间件的方法。这包括
Startup.Configure
. 中的代码
在 .NET 6 中,接口移动到 WebApplicationBuilder 和 WebApplication classes。 Program.cs
中的代码可以直接访问它需要的接口,而不是 .NET Core 调用“神奇的”Startup class 并注入接口。
- 主机 building/configuration 服务现在可以通过 WebApplicationBuilder class 获得。
- 完整的应用程序宿主提供的接口现在可以通过由 WebApplicationBuilder 构建的 WebApplication class 获得。
如果您不需要配置服务,您可以只用 3 行创建一个最小的 API 应用程序:
var app = WebApplication.Create(args);
app.MapGet("/", () => "Hello World!");
app.Run();
在您的情况下,您至少需要配置 DbContext,因此您需要分别使用 WebApplicationBuilder
和 WebApplication
。这将在下一节中显示
最小迁移 APIs
基本最小APIProgram.cs
:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
一旦通过 Services
属性:
WebApplication
实例,就可以创建 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();
当然 很多 更好地使用单独的方法或 classes 此类代码,保持 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
单独的扩展方法 class :
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;
}
}
在ASP.NET核心6中,应该是:
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<YourDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("YourConnectionString")));
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<YourDbContext>();
db.Database.Migrate();
}