ASP.NET Core测试:初始化内存SQLite DbContext时触发NullReferenceException
我之前也遇到过类似的问题,结合你的代码和报错信息,梳理几个最可能的原因和对应的解决方案:
1. 检查MYAPPDBContext的构造函数是否正确实现
EF Core的关系型数据库提供者(比如SQLite)要求你的DbContext必须有一个接收DbContextOptions<MYAPPDBContext>的构造函数,否则外部配置的SQLite选项无法被正确注入,直接导致内部连接对象初始化失败,抛出空引用异常。
确保你的DbContext类包含这样的构造函数:
public class MYAPPDBContext : DbContext { public MYAPPDBContext(DbContextOptions<MYAPPDBContext> options) : base(options) { } // 你的DbSet定义和其他配置代码... }
注:之前用EF Core内置的内存数据库(InMemory)时,可能不需要这个构造函数,但SQLite作为关系型数据库,必须依赖这个构造函数传递配置。
2. 移除多余的OpenConnection()调用
调用EnsureCreated()时,EF Core会自动负责连接的打开和初始化工作,手动提前调用context.Database.OpenConnection()反而会干扰内部的连接管理流程,在部分EF Core版本中,这会导致未完全初始化的连接对象被调用,从而触发空引用异常。
修改你的Create方法:
public static MYAPPDBContext Create() { var options = new DbContextOptionsBuilder<MYAPPDBContext>() .UseSqlite("DataSource=:memory:") .Options; var context = new MYAPPDBContext(options); // 移除这一行:context.Database.OpenConnection(); context.Database.EnsureCreated(); // 如果需要保持内存数据库的连接(避免连接关闭后数据丢失),可以这样处理 var connection = context.Database.GetDbConnection(); connection.Open(); return context; }
3. 确保EF Core与Microsoft.Data.Sqlite版本完全兼容
如果项目中EF Core和Microsoft.Data.Sqlite的版本不一致,极易导致内部组件初始化失败,抛出空引用异常。比如EF Core 6.x搭配Microsoft.Data.Sqlite 7.x,或者版本跨度过大的组合。
打开你的项目文件(.csproj),检查并确保两个包的版本完全一致:
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.25" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.25" />
4. 排查OnConfiguring方法是否覆盖了外部配置
如果你的MYAPPDBContext重写了OnConfiguring方法,且没有正确判断IsConfigured状态,可能会覆盖你在Create方法中设置的SQLite配置,导致连接对象异常。
避免这样的错误写法:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { // 错误:未检查IsConfigured,会覆盖外部传入的SQLite配置 optionsBuilder.UseSqlServer("YourDefaultConnectionString"); }
正确的写法应该是:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { // 仅当外部未配置时,才使用默认数据库配置 optionsBuilder.UseSqlServer("YourDefaultConnectionString"); } }
你可以先从检查构造函数和移除OpenConnection()这两个点开始尝试,这是此类问题最常见的诱因。
内容的提问来源于stack exchange,提问作者Laurie Dickinson

