【问题标题】:EF MigrateAsync() makes the controllers producing 404 Not FoundEF MigrateAsync() 使控制器产生 404 Not Found
【发布时间】:2021-12-15 02:23:38
【问题描述】:

在我的 Startup.cs 中,我执行这样的迁移。我无法解释的私有方法中有一些奇怪的问题,它似乎与调用的异步版本有关。以下内容按预期工作(尽管异步性毫无意义。

public async void Configure(
  IApplicationBuilder app, IWebHostEnvironment env)
{
  ...
  await MigrateDb(app);
  ...
}

private static async Task MigrateDb(IApplicationBuilder app)
{
  using IServiceScope scope = app.ApplicationServices
      .GetService<IServiceScopeFactory>()?.CreateScope();
  if (scope == null)
      throw new OperationCanceledException();

  Context context = scope.ServiceProvider.GetRequiredService<Context>();
  context.Database.Migrate();
}
    

但是,当我应用异步迁移时,东西停止工作。出于某种原因,控制器无法访问,我在每个端点上都得到了 404,包括 ping,它只从服务返回一个固定的字符串,而不与数据库有任何联系。

private static async Task MigrateDb(IApplicationBuilder app)
{
  using ...
  Context context = ...
  await context.Database.MigrateAsync();
}

谷歌搜索绝对没有提供任何相关信息。我尝试通过scope.Dispose(); 明确杀死范围。目前我不知道谷歌更多信息或如何解决故障。这不是一个关键的生产问题——我只是在做一个测试(这部分不是它的目的)。不过,理解为什么会发生这种情况会很有趣。

【问题讨论】:

    标签: c# entity-framework asynchronous database-migration asp.net-core-5.0


    【解决方案1】:

    我对 Configure 方法有些怀疑。异步任务和异步无效之间存在差异。有一个答案async/await - when to return a Task vs void? 将有助于理解这一点。

    总体 async void 未正确处理 MigrateAsnyc 的异步,这可能会导致问题。

    如果我必须尝试其他解决方案,那么我将使用 program.cs,您可以尝试一下。您必须使用自己的上下文。

    public class Program
        {
            public static async Task Main(string[] args)
            {
                var host = CreateHostBuilder(args).Build();
    
                //Migrate database
                var scope = host.Services.CreateScope();
                var context = scope.ServiceProvider.GetRequiredService<MyContext>();
                await context.Database.MigrateAsync();
    
                await host.RunAsync();
            }
    
            public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)            
                    .ConfigureWebHostDefaults(webBuilder =>
                    {
                        webBuilder.UseStartup<Startup>();
                    });
        }
    

    【讨论】:

    • 我想强调一点(据我所知),Configure(...) 上的 async 似乎并没有引起问题。当我真正使用迁移调用的异步版本时,奇怪的便便撞到了空气搅拌器。更奇怪的是——Swagger 似乎在同一个项目中运行良好。只有 我的 控制器得到了 404-bye-bye!什么庸医?!
    • 您是否尝试过我的选择,因为我觉得它仍然是 async void 和 migrateasync 的问题,因为当 async void 存在时,它不能正确返回到该线程,并且 swagger 可能正在工作,因为它可能在迁移操作之前配置,因此之后将在管道中配置。
    • 您还必须从 configure 方法中提供更多的东西。
    • 仅从配置中执行此操作是一个架构决定,因此 Startup.cs 是唯一允许的地方(出于各种原因)。基本上,它决定同步进行而不是在 Program.cs 中进行更改,所以我有点卡住了。至于您的建议,我之前曾尝试在启动应用程序之前运行异步内容并且它们有效(尽管我被指示将其删除)。所以我假设你对迁移的建议也有效(或者它在MainStartup 类中都失败了)。除非你能想到别的,否则就是这样。 :)
    猜你喜欢
    • 2015-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    • 2015-02-14
    相关资源
    最近更新 更多