繁体   English   中英

无法创建实体框架代码优先迁移

[英]Can't create Entity Framework code-first migrations

过去几周我一直在开发 .NET Core 6 控制台应用程序(不是 ASP.NET),现在我尝试实现 Entity Framework 6 迁移到它。

但是,即使我重用了使用迁移的工作数据库 model 中的一些代码,但现在我无法使其工作,并且由于缺少来自dotnet-ef的 output ,我也一直在苦苦挣扎。

由于我不记得的原因,我重用了来自使用的 Design-Time DbContext creation 的代码的数据库项目。 我不知道这是否是我进行迁移的最佳方式,但至少它设法在以前的项目中工作。 我以与之前相同的方式实现了所需的IDesignTimeDbContextFactory<DbContext>接口:

public class MySqlContextFactory : IDesignTimeDbContextFactory<MySqlContext>
{
    public MySqlContext CreateDbContext(string[] args)
    {
        DbContextOptionsBuilder optionsBuilder = new();
        ServerVersion mariaDbVersion = new MariaDbServerVersion(new Version(10, 6, 5));
        optionsBuilder.UseMySql(DatabaseCredentials.GetConnectionString(), mariaDbVersion);

        return new MySqlContext();
    }
}

public class MySqlContext : DbContext
{
    public DbSet<Endpoint> EndpointsSet { get; set; }
    
    private readonly string _connectionString;

    public MySqlContext() : base()
        => _connectionString = DatabaseCredentials.GetConnectionString();

    public MySqlContext(string connectionString) : base()
        => _connectionString = connectionString;

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => Configurator.Configure(optionsBuilder, _connectionString);

    protected override void OnModelCreating(ModelBuilder modelBuilder)
        => Configurator.Create(modelBuilder);
}

public static void Configure(DbContextOptionsBuilder optionsBuilder, string connectionString)
{
        ServerVersion mariaDbVersion = new MariaDbServerVersion(new Version(10, 6, 5));
        optionsBuilder.UseMySql(connectionString, mariaDbVersion);
}

public static void Create(ModelBuilder modelBuilder)
{
        IEnumerable<Type> types = ReflectionUtils.GetImplementedTypes(typeof(IEntityTypeConfiguration<>));
        if (types.Any())
        {
            foreach (Type entityConfigurationType in types)
            {
                modelBuilder.ApplyConfigurationsFromAssembly(entityConfigurationType.Assembly);
            }
        }
        else
        {
            Environment.Exit((int) EExitCodes.EF_MODEL_NOT_FOUND);
        }
}

但是,当我尝试创建第一个迁移时,我收到了来自 dotnet-ef 工具的这个绝对非描述性 output 的提示:

PS> dotnet ef migrations add Init
Build started...
Build succeeded.
PS>

但是我的项目没有进行任何迁移,也没有任何改变。 所以我决定通过在 PS 命令上附加--verbose标志来强制 dotnet ef 告诉我更多信息:

[...]
Build succeeded.
dotnet exec --depsfile F:\pablo\Documents\source\MyBot\bin\Debug\net6.0\MyBot.deps.json --additionalprobingpath C:\Users\pablo\.nuget\packages --runtimeconfig F:\pablo\Documents\source\MyBot\bin\Debug\net6.0\MyBot.runtimeconfig.json C:\Users\pablo\.dotnet\tools\.store\dotnet-ef\6.0.1\dotnet-ef\6.0.1\tools\netcoreapp3.1\any\tools\netcoreapp2.0\any\ef.dll migrations add Init -o Migrations\Init --assembly F:\pablo\Documents\source\MyBot\bin\Debug\net6.0\MyBot.dll --project F:\pablo\Documents\source\MyBot\MyBot.csproj --startup-assembly F:\pablo\Documents\source\MyBot\bin\Debug\net6.0\MyBot.dll --startup-project F:\pablo\Documents\source\MyBot\MyBot.csproj --project-dir F:\pablo\Documents\source\MyBot\ --root-namespace MyBot--language C# --framework net6.0 --nullable --working-dir F:\pablo\Documents\source\MyBot--verbose

Using assembly 'MyBot'.
Using startup assembly 'MyBot'.
Using application base 'F:\pablo\Documents\source\MyBot\bin\Debug\net6.0'.
Using working directory 'F:\pablo\Documents\source\MyBot'.
Using root namespace 'MyBot'.
Using project directory 'F:\pablo\Documents\source\MyBot\'.
Remaining arguments: .
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Found IDesignTimeDbContextFactory implementation 'MySqlContextFactory'.
Found DbContext 'MySqlContext'.
Finding application service provider in assembly 'MyBot'...
Finding Microsoft.Extensions.Hosting service provider...
No static method 'CreateHostBuilder(string[])' was found on class 'Program'.
No application service provider was found.
Finding DbContext classes in the project...
Using DbContext factory 'MySqlContextFactory'.
PS>

我认为我可以搜索的第一件事是CreateHostBuilder function 该工具正在搜索但不检索。 然而,再一次,我能找到的所有文档都是指 ASP.NET 应用程序,以及我没有在我的机器人应用程序中实现的编程模式。 我的应用程序确实通过定制的依赖注入检索服务(也许这就是No application service provider was found. ?),但我没有找到一种方法来实现 CreateHostBuilder function 而不改变一切。

仅用于添加信息,这就是我设法使用非迁移方法创建和配置 EF model 的方式:

public static IServiceProvider GetServices(DiscordSocketClient client, CommandService commands)
    {
        ServiceCollection services = new();

        services.AddSingleton(client);
        services.AddSingleton(commands);
        services.AddSingleton<HttpClient>();

        services.AddDbContext<MySqlContext>(ServiceLifetime.Scoped);

        return AddServices(services) // builds service provider;
    }

private static async Task InitDatabaseModel(IServiceProvider provider)
    {
        MySqlContext? dbCtxt = provider.GetService<MySqlContext>();

        if (dbCtxt == null)
        {
            Environment.Exit((int) EExitCodes.DB_SERVICE_UNAVAILABLE);
        }

        await dbContext.Database.EnsureDeletedAsync();
        await dbContext.Database.EnsureCreatedAsync();
    }

但不幸的是,我的应用程序计划与数据库进行动态交互,因此 Code-First 配置方法对我无效。

我该如何解决这个问题? 是方法问题,还是我在搞乱自定义非 ASP.NET 依赖注入提供程序? 谢谢你们

您的IDesignTimeDbContextFactory存在问题。 EF Core 正在尝试为您的这个工厂创建一个MySqlContext

public class MySqlContextFactory : IDesignTimeDbContextFactory<MySqlContext>
{
    public MySqlContext CreateDbContext(string[] args)
    {
        // set up options
        DbContextOptionsBuilder optionsBuilder = new();
        ServerVersion mariaDbVersion = new MariaDbServerVersion(new Version(10, 6, 5));
        optionsBuilder.UseMySql(DatabaseCredentials.GetConnectionString(), mariaDbVersion);
        
        // *** this is the issue *** 
        // return default constructor W/O options (ie, UseMySql is never called)
        return new MySqlContext(); 
    }
}

您可以将此构造函数添加到您的DbContext class:

public MySqlContext(DbContextOptions<MySqlContext> options)
        : base(options)
    {
    }

然后从您的工厂return new MySqlContext(optionsBuilder.Options)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM