在.NET Core Web应用程序的启动类中,app.UseMigrationsEndPoint函数有什么作用?

40

我从Visual Studio创建了一个新的.NET Core Web应用程序,生成了以下代码片段于启动类中:

if (env.IsDevelopment())
{
    // ***
    app.UseMigrationsEndPoint();
    // ***
}
这行代码 app.UseMigrationsEndPoint() 到底是做什么的呢?官方文档并没有提供有用的信息:

该中间件会处理请求来执行迁移操作。中间件将会监听 DefaultPath 的请求。

那么什么是默认路径?需要发送什么 POST 请求才能触发它?它最终会执行什么操作?这个方法是否支持可选参数?它是否受到某种保护?

1
有什么不清楚的吗?文档中提到了一个静态的 MigrationsEndPointOptions.DefaultPath 字段,它是同一类中 Path 属性的默认值。在输入该属性时,您应该能够看到该值或者在 源代码 中查看。 - Tseng
14
没错,所有资料都可以在源代码中找到。我想我习惯了 MSDN 时代,那时微软的文件覆盖面很广。现在要看文档就得 RTFS(Read The F**king Source)了。 - Miroslav Zadravec
4个回答

37

app.UseMigrationsEndPoint() 在开发中是一个非常方便的工具。

在我们开发过程中,我们会向数据库上下文中添加实体,或修改已有实体。通常,我们会像往常一样运行dotnet ef migrations add <NameOfMigration>来生成迁移文件。当migrations add命令成功后,我个人通常会运行dotnet ef database update。但是,有了app.UseMigrationsEndPoint(),我就不必手动运行dotnet ef database update

因此,在开发中我们尝试构建和运行我们的应用程序。浏览器加载我们的应用程序,但是我们可能没有按照预期进行database update

然而,如果我们尝试访问需要访问尚未更新的表的页面或API调用,我们将得到一个特殊的页面 - 不是错误页面 - 而是列出所有尚未应用的迁移的页面。

令人惊讶的是,有一个标有“应用迁移”的按钮(或类似的东西)。我们会点击它,然后根据尚未应用的迁移来更新我们的数据库。然后我们重新加载页面,浏览器将显示我们期望的页面。我们可以检查SQL Server Object Explorer或其他工具中的表,我们会看到那些迁移被反映出来。


2
这个答案比被采纳的那个好多了。 - Jonathan E. Landrum

26

你可能已经从链接的文档页面中看到了,它来自于 EF Core。将要运行的确切代码可以在 GitHub 上找到。

它检查所使用的数据库是否有任何未执行的迁移,并在需要时应用它们。就是这样。


感谢澄清。我仍然对ASP.NET网站如何在数据库迁移未完全应用的情况下运行感到困惑。我的意思是,难道不应该在网站启动之前运行数据库迁移吗?当网站正在运行时,如何向运行时引入新的数据库迁移呢?即使这是可能的,那也不会很危险吗?我想我可能错过了某种情景。 - XDS
1
为了支持上述场景,存在这段代码。这意味着您将新版本部署到生产槽位,从而导致应用程序重新启动。在此重新启动期间,迁移将被应用,之后新代码开始运行。从而实现最小化停机时间。 - Oliver
1
此外,只要模式更改仅为添加性质且不包含任何新的键约束(例如,您向表中添加一个简单列),EF 就可以使用旧设计,并且无法查看或使用此列,这意味着如果您的代码添加了新实体,则它们必须支持空值或 SQL 模式必须在过渡阶段提供有意义的默认值。 - Oliver

0

默认路径是什么?...

/ApplyDatabaseMigrations 是 aspnetcore 的主要路径,截至 2023 年 02 月 08 日 (二月)。

...需要POST什么内容?它实际执行什么?它有任何可选参数吗?它受到保护吗?

我认为这些问题已在上面或注释中回答。


1
仅仅因为它没有在文档中提到,并不意味着这个选择是合适的,也不意味着我们在这里必须像他们一样没有帮助。 - yzorg

0

这是在 GitHub 上初始化 DefaultPath 字段的确切代码行:

Diagnostics.EntityFrameworkCore/src/MigrationsEndPointOptions.cs:18

在这里,您可以看到该值设置为"/ApplyDatabaseMigrations"

public class MigrationsEndPointOptions
{
    /// <summary>
    /// The default value for <see cref="Path"/>.
    /// </summary>
    public static PathString DefaultPath = new PathString("/ApplyDatabaseMigrations");

    // ...

我添加了这个答案,因为它提供了确切的源代码位置和实际值。 - nam20485

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接