.NET 6 如何在 program.cs 中自动运行迁移
Posted
技术标签:
【中文标题】.NET 6 如何在 program.cs 中自动运行迁移【英文标题】:.NET 6 how to run Migration automatically in program.cs 【发布时间】:2021-12-07 20:18:02 【问题描述】:在.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 中做到这一点?
【问题讨论】:
不确定您在说什么,自 .NET Core 2.0 于 2017 年发布以来,在 Startup 中进行迁移和播种已被弃用。简单的搜索会有所帮助 ***.com/a/45942026/455493。可能有点过时了,方法也略有改动,大体思路是一样的 有什么问题? Applying Migrations at Runtime 表明dbContext.Database.Migrate()
没有改变。您是在问将以前在 Startup.Configure
中的代码放在哪里?
顺便说一句,感谢您帮助我阐明从 Startup.cs 到我脑海中最小 API 的变化。到目前为止,我主要通过检查哪个类具有我需要的属性来编写正确的代码。这是它第一次真正点击去哪里以及为什么。
【参考方案1】:
短版
听起来真正的问题是把过去存在于 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
方法中,或者,如果使用最小API,则放在Program.cs
中。 Configuration
、Services
、Environment
等可用作 WebApplicationBuilder 类或由它创建的 WebApplication 中的属性。 WebApplicationBuilder
包含用于 DI、配置、日志记录和主机的构建器接口,例如 WebApplicationBuilder.Services
公开 IServiceCollection
。
WebApplication
属性暴露WebApplicationBuilder
配置的中间件,例如WebApplication.Services
暴露IServiceProvider
Minimal API 中的启动替换
Startup.cs
中的方法在 .NET 6 中被合并到 Program.cs
中。Startup.cs 包含两种方法:
IServiceCollection
、IConfigurationBuilder
等各种构建器接口来配置主机和应用程序的方法,例如设置配置和DI。这包括以前在 Startup.ConfigureServices
中的代码。
使用主机配置端点、使用服务和中间件的方法。这包括 Startup.Configure
中的代码。
在 .NET 6 中,接口移至 WebApplicationBuilder 和 WebApplication 类。 Program.cs
中的代码可以直接访问它需要的接口,而不是 .NET Core 调用“神奇”的 Startup 类并注入接口。
如果您不需要配置服务,您可以只用 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();
一旦通过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();
当然,最好很多为这样的代码使用单独的方法或类,保持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;
【讨论】:
你就是男人!【参考方案2】:在 ASP.NET Core 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();
【讨论】:
仅代码答案只有在显而易见的情况下才可接受。这个不是。如果 OP 知道如何检索其 DbContext 的实例或替换Startup
方法的方法,则 OP 不会发布问题以上是关于.NET 6 如何在 program.cs 中自动运行迁移的主要内容,如果未能解决你的问题,请参考以下文章
如何在 .NET 6 最小 API Program.cs 中访问 DbContext
将依赖项传递给 .NET 6 中 program.cs 中的 app.[Methods()]
从 .net 6 的代码覆盖范围中排除 Program.cs [重复]