为什么应用程序以 dotnet ef migrations add 启动?

hoo*_*ozr 7 c# entity-framework-core entity-framework-migrations ef-core-6.0

我在 VS2019 的开发人员 PowerShell 中使用 EF Core 工具时出现奇怪的行为。

使用此命令创建迁移后:

dotnet ef migrations add VisibleLink -p .\src\Only.Portal.Data\ -s .\src\Only.Portal.Web
Run Code Online (Sandbox Code Playgroud)

它导致启动我的应用程序,但以前没有。应用最后迁移的方法,这会导致dotnet ef migrations remove完全损坏,因为使用它时,它首先启动一个应用程序,然后调用`Migrate()。

然后我收到一条消息:

迁移“20220128090939_VisibleLink”已应用于数据库。恢复并重试。如果迁移已应用于其他数据库,请考虑使用新的迁移来恢复其更改

看起来像是死循环。

Ren*_*ers 5

我对作者自己标记为已接受解决方案的答案不满意。我不清楚这里真正的“解决方案”是什么。仅提到应该“使用启动”。没有提及实际解决问题的具体内容。

我正在运行一个具有最少启动 API 的 .NET 6 ASP.NET 应用程序,并遇到了同样的问题。dotnet ef migrations会调用我的启动代码,导致整个应用程序尝试启动,然后失败(特别是我有一个在启动时直接运行的服务,它尝试使用我正在积极尝试为其创建迁移的数据库表)。

我通过放弃最小的 API 并Program使用“假”public static IHostBuilder CreateHostBuilder方法创建一个类来解决这个问题。

public class Program
{
    // Have a Main that actually runs/starts your app with all the logic
    public static async Task Main(string[] args)
    {
        // Here I do automatic migrations...
        // ...

        // Web app initialization logic
        var builder = WebApplication.CreateBuilder(args);
        builder.Services.AddRazorPages();

        var app = builder.Build();

        app.UseAuthentication();
        app.UseAuthorization();
        app
            .MapControllers()
            .RequireAuthorization();
        // etc.

        await app.RunAsync();
    }
    
    // Have a CreateHostBuilder that simply returns a default builder.
    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        Console.WriteLine("Doing Entity Framework migrations stuff, not starting full application");
        return Host.CreateDefaultBuilder();
    }
}
Run Code Online (Sandbox Code Playgroud)

EF 将CreateHostBuilder在Program. 如果找到它,它不会调用Main,并且基本上跳过 web 应用程序的整个初始化并返回一个非常空的主机构建器,足以让 EF 完成其工作。

这感觉有点像黑客,以后可能不起作用。

为 EF Core 7.0+ 用户提供更好的解决方案

如果您使用 EF Core 7.0 或更高版本,请参阅此答案。现在,当EF.IsDesignTime为:时,您可以返回空主机构建器true:

// Program.cs

if (EF.IsDesignTime) {
    new HostBuilder().Build().Run();
    return;
}

// Normal startup
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();

var app = builder.Build();

app.UseAuthentication();
// ...
Run Code Online (Sandbox Code Playgroud)