在Heroku中运行EF Core迁移

3
我目前正在使用.NET Core开发原型,并为简单起见,采用Docker/Heroku。但是当我尝试通过“heroku dotnet run ef database update”运行迁移时,遇到了“dotnet” CLI不可用的问题。我很快意识到这是由于我的最终镜像仅具有运行时而没有SDK。我的问题是:为了能够运行迁移,同时只运行运行时的较轻镜像,哪个方案最合理?我是否过分关注只有运行时的问题?
以下是我当前的镜像,为了能够如我目前所做的那样运行迁移:
FROM mcr.microsoft.com/dotnet/core/sdk:3.0
WORKDIR /app
COPY --from=build-env /app/out ./

RUN dotnet tool install --global dotnet-ef

# Set ASPNETCORE_URLS to run the app on the port Heroku exposes.
# Kestrel run by default on 5000/1 and Heroku doesn't allow that.
CMD ASPNETCORE_URLS=http://*:$PORT dotnet Lazarus.dll

我觉得在生产镜像中既要安装SDK又要安装EF CLI感觉不太对,欢迎提供任何见解!


我也觉得在生产 Docker 镜像上安装 SDK 和 EF 是不合适的。在我看来,数据库迁移是部署步骤,而不是后期生产活动。因此,在部署过程中,我会使用从 Docker Hub 上预构建的带有 EF 的 SDK 镜像,将迁移脚本挂载到镜像上,设置连接信息为环境变量并执行迁移命令。然后将轻量级容器推送到生产环境中。 - Sai Puli
对,我只是有些不确定该如何实现,至少不是以一种简洁的方式。 - Javier García Manzano
我遇到了这个问题,这让我放心,因为我不是唯一一个遇到这个问题的人:https://github.com/aspnet/EntityFrameworkCore/issues/15857 - Javier García Manzano
1个回答

5

在尝试了不同的选项后,最简单的方法是在应用程序代码中连接到webhost,并在启动之前运行迁移。

通过创建一个扩展函数,例如:

public static IWebHost MigrateDatabase<T>(this IWebHost webHost) where T : DbContext
{
    using(var scope = webHost.Services.CreateScope())
    {
        var services = scope.ServiceProvider;
        try
        {
            var db = services.GetRequiredService<T>();
            db.Database.Migrate();
        }
        catch (Exception ex)
        {
            var logger = services.GetRequiredService<ILogger<Program>>();
            logger.LogError(ex, "An error occurred while migrating the database.");
        }
    }
    return webHost;
}

它可以在主入口点中按照以下方式使用:

public static void Main(string[] args)
{
    CreateWebHostBuilder(args)
        .Build()
        .MigrateDatabase<DatabaseContext>()
        .Run();
}

虽然它不在部署过程中运行迁移,而是作为启动过程的一部分运行,但我认为这样做更容易且需要的组件更少才能开始。这也允许发运一个更小的镜像,其中只包含运行时而不是带有所有工具的SDK。

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