.NET 5控制台应用appsettings.json未加载及EF5迁移报错问题
问题根因
- .NET 5控制台应用默认不会自动加载appsettings.json,和ASP.NET Core的默认模板逻辑不同,控制台项目初始模板没有集成配置加载的相关逻辑,你代码里只声明了
static IConfiguration config但从未做实例化赋值,直接调用读取方法必然触发空引用异常。 - 迁移时报
Format of the initialization string does not conform to specification starting at index 0,是因为你给-connection参数传入的entities是配置项的键名,不是实际的连接字符串内容,EF Core工具直接将这个字符串作为连接串解析,自然不符合格式要求。 - 注释硬编码逻辑后报
No database provider has been configured for this DbContext,是因为EF Core迁移工具执行时会优先查找DbContext的无参构造实例,你既没有在OnConfiguring中配置数据库提供程序,也没有给工具提供可读取的配置源,工具无法生成可用的DbContext实例。 - 额外注意:你当前appsettings.json里的连接串缺少
Initial Catalog=Test配置,和你之前硬编码的连接串不一致,即使加载成功也会默认连接到master库,不会生成表到你预期的Test库。
修复步骤
1. 安装依赖包
通过NuGet包管理器安装以下三个包:
Microsoft.Extensions.Configuration.Json:提供json配置文件加载能力Microsoft.EntityFrameworkCore.Design:EF Core迁移工具运行的必需依赖,控制台项目默认不会预装Microsoft.EntityFrameworkCore.SqlServer:SQL Server数据库提供程序(如果之前装过可以忽略)
2. 配置appsettings.json的复制属性
右键解决方案资源管理器中的appsettings.json文件,选择「属性」,将「复制到输出目录」选项设置为如果较新则复制,避免生成输出时配置文件没有被拷贝到运行目录导致加载失败。
同时修正连接串配置,补全Initial Catalog字段:
{ "ConnectionStrings": { "Entities": "Data Source=(LocalDB)\\MSSQLLocalDB;Initial Catalog=Test;Integrated Security=True;" } }
3. 修正Program.cs的配置初始化逻辑
不要只声明IConfiguration字段不赋值,在Main方法入口先完成配置构建:
private static IConfiguration config; static void Main() { // 构建配置实例,加载appsettings.json config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .Build(); // 此时可以正常读取到连接串 string conn = config.GetConnectionString("Entities"); // 通过构造函数传入连接串,不要在DbContext里硬编码 using (Entities context = new Entities(conn)) { var rbts = context.Students.ToList(); foreach (var rbt in rbts) { Console.WriteLine("{0} {1}", rbt.Name, rbt.ID); } } }
4. 改造DbContext,兼容运行时和迁移场景
修改Entities.cs,移除硬编码逻辑,增加接收连接串的构造函数,同时给迁移工具提供配置读取入口:
public partial class Entities : DbContext { private readonly string _connectionString; // 无参构造供EF Core设计时工具调用 public Entities() { } // 运行时通过该构造传入从配置读取的连接串 public Entities(string connectionString) { _connectionString = connectionString; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { // 优先使用运行时传入的连接串,迁移场景下从项目根目录的appsettings.json读取 var connStr = _connectionString ?? LoadConnectionStringForDesignTime(); optionsBuilder.UseSqlServer(connStr); } } // 迁移场景下的配置读取逻辑 private static string LoadConnectionStringForDesignTime() { // 迁移工具运行时的工作目录是bin下的输出文件夹,需要定位回项目根目录找appsettings.json var projectRootPath = Path.Combine(Directory.GetCurrentDirectory(), "..\\..\\..\\"); var config = new ConfigurationBuilder() .SetBasePath(projectRootPath) .AddJsonFile("appsettings.json") .Build(); return config.GetConnectionString("Entities"); } public DbSet<Student> Students { get; set; } }
5. 执行迁移
不需要额外传-connection参数,EF工具会自动通过设计时逻辑读取配置,直接在包管理器控制台执行以下命令即可:
Add-Migration InitialCreate -Context Entities Update-Database -Context Entities
如果确实需要指定其他数据库做迁移,直接将完整的连接字符串内容作为-connection的参数值传入,不要只传配置键名,否则会出现之前的格式解析错误。
内容的提问来源于stack exchange,提问作者Nime Cloud
相关产品推荐
相关产品推荐

