控制台应用运行时可加载用户机密但设计时执行Add-Migration无法加载的问题
控制台应用运行时可加载用户机密但设计时执行Add-Migration无法加载的问题
嗨,我太懂你这个糟心的问题了——控制台程序跑起来的时候,用户机密能正常加载,连你写的遍历配置的代码都能打出机密内容;可一到用Package Manager Console执行Add-Migration这类EF Core设计时命令,就完全找不到用户机密的影子了,对吧?
这其实是因为EF Core的设计时工具(比如Add-Migration、Update-Database)默认不会自动复用你在Main方法里搭建的IHost配置逻辑,它会自己尝试初始化DbContext,这就跳过了用户机密的加载步骤。
给你两个靠谱的解决办法,优先推荐第一个:
方法一:实现IDesignTimeDbContextFactory复用运行时配置
你只需要在项目里新建一个类,实现IDesignTimeDbContextFactory<ApplicationDbContext>接口,让EF Core设计时工具用你现有的Host配置来创建DbContext:
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; public class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext> { public ApplicationDbContext CreateDbContext(string[] args) { // 直接复用你Main方法里的Host创建逻辑,保证配置和运行时完全一致 var host = Host.CreateDefaultBuilder(args) .ConfigureServices((context, services) => { services.AddDbContext<ApplicationDbContext>(); }) .Build(); // 从Host的服务容器里取出DbContext实例 return host.Services.GetRequiredService<ApplicationDbContext>(); } }
这个类会告诉EF Core:“别自己瞎初始化DbContext了,用我这个方法来创建,我这里用的和运行时一模一样的配置,用户机密自然就加载进来了”。
方法二:在OnConfiguring里手动加载用户机密
这个方法虽然能解决问题,但会重复配置逻辑,不如第一个优雅,适合临时应急:
using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using System.IO; public class ApplicationDbContext : DbContext { public DbSet<TestRequest> TestRequests { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { var configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddUserSecrets<ApplicationDbContext>() // 手动指定加载当前类对应的用户机密 .Build(); // 用加载好的配置设置数据库连接 optionsBuilder.UseSqlServer(configuration.GetConnectionString("YourConnectionStringName")); // 现在遍历configuration就能看到用户机密内容了 foreach (var item in configuration.AsEnumerable()) { Console.WriteLine($"{item.Key}: {item.Value}"); } } } }
注意AddUserSecrets的泛型参数要选你项目里的一个类(比如这里的ApplicationDbContext),这样工具才能定位到正确的用户机密文件。
推荐你用第一个方法,这样配置逻辑完全复用,以后不管是改appsettings还是用户机密,都不用在多个地方改代码,维护起来省心多了。
备注:内容来源于stack exchange,提问作者iKingNinja
相关产品推荐
相关产品推荐

