asp.net - 无法在 MySql DbContext 的 dotnet ef 迁移中创建对象错误,但适用于 Sqlite DbContext

标签 asp.net entity-framework asp.net-core

我为新的 ASP.Net Core 应用程序创建了 2 个 DbContext。

https://github.com/jonasarcangel/IdentityMigrationsForMySql/tree/master/IdentityMigrationsForMySql/Server/Data

它们都派生自相同的 ApplicationDbContext 基类,唯一的区别是 OnConfiguring 重写,其中使用 UseMySql 而不是 UseSqlite,遵循此 post about multiple providers 中的建议。 .

SqliteDbContext.cs 有这个:

        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
#if DEBUG_EF
            options.UseSqlite("DataSource=");
#endif
        }

MySqlDbContext.cs 有这个:

        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
#if DEBUG_EF
            options.UseMySql("Server=");
#endif
        }

运行以下命令:

dotnet ef migrations add InitialCreate --context MySqlDbContext --output-dir Migrations/MySql --configuration DebugEf

返回的错误是:

Unable to create an object of type 'MySqlDbContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

但是,使用 Sqlite 上下文的以下命令是成功的。

dotnet ef migrations add InitialCreate --context SqliteDbContext --output-dir Migrations/Sqlite --configuration DebugEf

最佳答案

这是因为在你的 ConfigureServices 中方法,您显式配置 SqliteDbContext:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<SqliteDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));
            ...
        }

如果您将代码更改为 AddDbContext<MySqlDbContext>,则会成功创建迁移,但是这样会破坏 Sqlite 构建。

如果您继续阅读链接的文章,他们描述了如何解决此问题:

In your application, you should continue to use MyDb. However, for EF to determine which migration to use, you have to call services.GetService<T> where T is one of the subclasses (instead of MyDb).

Therefore, in Startup.ConfigureServices, register the subclasses:

// Configure database 
switch (config.DbProvider.ToLower()) {
case "sqlite": {
    services.AddDbContext<MyDb>(options => { options.UseSqlite(config.DbConnString); });
    services.AddDbContext<SqliteMyDb>(options => { options.UseSqlite(config.DbConnString); });
}
    break;
case "postgres": {
    services.AddDbContext<MyDb>(options => options.UseNpgsql(config.DbConnString));
    services.AddDbContext<NpgsqlMyDb>(options => options.UseNpgsql(config.DbConnString));
}
    break;
default: {
    throw new Exception($"DbProvider not recognized: {config.DbProvider}");
} } 

Then, in Startup.Configure, do the migrations:

void ProcessDb<T>()
where T : MyDb {
    using var db = services.GetService<T>();
    db.Database.Migrate();

    // ... perform other startup tasks with db }

switch (config.DbProvider.ToLower()) {
    case "sqlite": {
        ProcessDb<SqliteMyDb>();
        break;
    }
    case "postgres": {
        ProcessDb<NpgsqlMyDb>();
        break;
    }
    default: {
        throw new Exception();
    } } 

In summary, for each extra provider, add one subclass, a two-line case in ConfigureServices, and a case in Configure.

关于asp.net - 无法在 MySql DbContext 的 dotnet ef 迁移中创建对象错误,但适用于 Sqlite DbContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64985292/

相关文章:

c# - 包含相同对象列表的对象的 Entity Framework 映射

c# - 对于对未映射 URL 的未经身份验证的请求,ASP.NET Core Minimal API 返回 404 代码而不是 401

asp.net - 在 ASP.net Core 中填充下拉列表

c# - asp.net c# 文本框 onclick 如果默认文本为空。如果不是默认文本则保持不变

entity-framework - EF Code First 错误地重命名表,这是一个错误吗?

c# - Web 应用程序无法运行

c# - 如何使用 ASP.NET Core/Razor 通过单击按钮运行在 Razor 页面上编写的 C#?

c# - MVC 4.5.2 Response.WriteFile 大于 2gb

c# - 在 asp.net 应用程序中启用 c# 7

.net - 支持 SQL Server 2005 和 2008