You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#模拟DbContext属性调试显值但触发空引用异常问题

调试DbContext属性时的NullReference异常问题

问题现象

  • 调试悬停DbContext容器类时,Persons属性显示存在值(以Castle.Proxies.开头),且Results View中显示包含一个元素的List(符合预期)。
  • 直接引用该属性时,悬停显示为NULL,调用操作会触发NullReferenceException。

容器类定义

public interface IBrokerContext : IDisposable
{
    DbSet<Agents> Agents { get; set; }
    
    IDbContextTransactionProxy BeginTransaction();
}

public class BrokerContext : ApplicationDbContext, IBrokerContext
{
    public new DbSet<Agents> Agents { get; set; }
    ...
}

BrokerContext作为ApplicationDbContext的代理/适配器,用于模拟BeginTransaction()方法。

场景说明

业务代码中使用ApplicationDbContext类型的_db实例,该实例包含BrokerContext中声明的集合。测试时尝试构造BrokerContext的模拟对象,传入被测试类以覆盖ApplicationDbContext,从而控制BeginTransaction()的行为。

执行mockDb.Object.Agents = mockAgentSet.Object赋值后,调试视图显示_db.Agents有值,但引用await _db.Agents时却返回null!

被覆盖的DbContext定义

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public virtual DbSet<Agents> Agents { get; set; }
    ...
}

问题原因

核心是**new关键字隐藏基类成员**的特性导致的:

  • BrokerContext中用new声明的Agents属性,仅隐藏了基类ApplicationDbContext的同名属性,并未重写。
  • 业务代码里的_db是ApplicationDbContext编译时类型,访问_db.Agents时,实际调用的是基类的virtual属性,而非BrokerContext里的新属性。
  • 调试器显示的是实例运行时类型(BrokerContext)的成员,因此能看到赋值后的新属性值,但代码执行遵循编译时类型的访问规则,基类属性未被赋值,所以返回null。

解决方法

方法1:重写基类属性(推荐)

去掉BrokerContext中的new关键字,改用override重写基类的virtual属性,确保编译时和运行时的属性访问一致:

public class BrokerContext : ApplicationDbContext, IBrokerContext
{
    public override DbSet<Agents> Agents { get; set; }
    ...
}

方法2:调整业务代码的依赖类型

将业务代码中_db的类型改为IBrokerContext,直接访问接口定义的Agents属性,对应到BrokerContext的实现:

// 业务代码中修改依赖注入的类型
private readonly IBrokerContext _db;

public YourService(IBrokerContext db)
{
    _db = db;
}

内容的提问来源于stack exchange,提问作者HelloWorld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:21:35