EF Core 2.0:附属程序集含DbContext时迁移命令报错问题
我之前也踩过这个坑——把DbContext单独放在类库项目里,直接在类库目录跑dotnet ef migrations add就会弹出这个“未配置数据库提供程序”的报错。其实原因很直白:EF Core CLI不知道该去哪找你的数据库连接字符串和提供程序配置,毕竟这些东西都在主API项目的Startup里呢。下面给你几个实用的解决办法:
方法一:指定启动项目(最省心的方案)
不用切换到主API项目目录,直接在附属程序集的命令行里加上--startup-project参数,指向你的主API项目路径就行。命令改成这样:
dotnet ef migrations add UserAccountFields --startup-project ../你的主API项目名称
注意这里的../是相对路径,得根据你的解决方案文件夹结构调整,确保能精准定位到主API的根目录。这样EF CLI就会加载主API里的所有配置,找到你在Startup.ConfigureServices中用AddDbContext注册的数据库提供程序和连接字符串了。
方法二:给DbContext添加OnConfiguring方法
如果不想每次都敲启动项目参数,也可以直接在你的DbContext类里重写OnConfiguring方法,直接硬编码数据库配置(提醒一下:别把敏感的连接字符串提交到代码仓库哦):
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { // 这里换成你用的数据库提供方法,比如MySQL用UseMySQL,PostgreSQL用UseNpgsql optionsBuilder.UseSqlServer("你的数据库连接字符串"); } }
这样EF CLI在类库项目里就能直接获取到配置了,不过缺点是主项目的连接字符串更新后,这里也要同步修改,容易出现配置不一致的问题,所以只适合简单场景。
方法三:临时启动类(适配复杂配置场景)
如果你的主项目用了环境变量、分层配置文件这类复杂的配置方式,上面两种方法可能不够用,这时候可以在附属程序集里加一个临时的启动类,让EF CLI能正确加载配置:
- 在附属程序集里新建一个类,比如
EfMigrationStartup.cs:
public class EfMigrationStartup { public IConfiguration Configuration { get; } public EfMigrationStartup() { var builder = new ConfigurationBuilder() // 指向主API项目的配置文件目录 .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../你的主API项目名称")) .AddJsonFile("appsettings.json") .AddEnvironmentVariables(); Configuration = builder.Build(); } public void ConfigureServices(IServiceCollection services) { services.AddDbContext<你的DbContext类>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); } }
- 然后在命令行里指定这个启动类:
dotnet ef migrations add UserAccountFields --startup-project . --project ../你的主API项目名称 --startup-class EfMigrationStartup
这个方法虽然麻烦点,但能完美适配复杂的配置场景,适合大型项目使用。
总的来说,方法一是最推荐的,简单直接还能复用主项目的所有配置,不会出现配置不一致的问题,绝大多数场景下用它就够了。
内容的提问来源于stack exchange,提问作者Jammer

