7

在 .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 中做到这一点?

4

2 回答 2

11

精简版

听起来真正的问题是把过去的代码放在哪里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,ServicesEnvironment可用作WebApplicationBuilder类或由它创建的WebApplication中的属性。WebApplicationBuilder包含 DI、配置、日志记录和主机的构建器接口,例如WebApplicationBuilder.Services暴露IServiceCollection

WebApplication属性暴露由 配置的中间件WebApplicationBuilder,例如WebApplication.Services暴露IServiceProvider

Minimal 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可以直接访问它需要的接口。

如果你不需要配置服务,你可以只用 3 行创建一个最小的 API 应用程序:

var app = WebApplication.Create(args);

app.MapGet("/", () => "Hello World!");

app.Run();

在您的情况下,您至少需要配置 DbContext,因此您需要单独使用WebApplicationBuilderWebApplication。这将在下一节中显示

最小 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;
    }
}
于 2021-12-08T07:36:47.543 回答
5

在 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();
}
于 2021-12-08T07:46:40.733 回答