我为新的 ASP.Net Core 应用程序创建了 2 个 DbContext。
它们都派生自相同的 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 callservices.GetService<T>
where T is one of the subclasses (instead ofMyDb
).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/