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

ASP.NET Core 8 Web API执行Add-Migration时DbContext创建失败

ASP.NET Core 8 Web API Add-Migration 空引用异常解决

执行Add-Migration InitialMigrations命令时触发错误:

Unable to create a 'DbContext' of type 'AMSContext'. The exception 'Object reference not set to an instance of an object.' was thrown while attempting to create an instance.

相关代码片段

AMSContext.cs

public partial class AMSContext : BaseContext
{
    private readonly ICurrentUser _currentUser;

    public AMSContext(DbContextOptions<AMSContext> options,
        ICurrentUser currentUser
        ) : base(options)
    {
        _currentUser = currentUser;
    }
    // Dbsets 定义
}

BaseContext.cs

public abstract class BaseContext : IdentityDbContext<ApplicationUser, ApplicationRole, int, IdentityUserClaim<int>, IdentityUserRole<int>, IdentityUserLogin<int>, ApplicationRoleClaim, IdentityUserToken<int>>
{
    protected BaseContext(DbContextOptions options) : base(options)
    {

    }
    
}

Program.cs 配置

services.AddDbContext<AMSContext>(options =>
{
    options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"), o =>
    {
        o.CommandTimeout((int)TimeSpan.FromMinutes(2).TotalSeconds);
        o.MigrationsAssembly(Assembly.GetAssembly(typeofMSContext))!.FullName);
    });
    options.EnableSensitiveDataLogging();
});

错误根源分析

  1. Program.cs语法错误:Assembly.GetAssembly(typeofMSContext)存在语法错误,正确写法应为Assembly.GetAssembly(typeof(AMSContext)),缺失括号导致Assembly.GetAssembly返回null,后续!.FullName触发空引用异常。
  2. 设计时依赖缺失:EF Core设计时创建DbContext时,不会完整启动Web应用的服务容器,ICurrentUser依赖无法被正常注入,也会导致实例化失败。

解决方案

方案1:修复Program.cs语法错误

修正迁移程序集配置的语法问题:

services.AddDbContext<AMSContext>(options =>
{
    options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"), o =>
    {
        o.CommandTimeout((int)TimeSpan.FromMinutes(2).TotalSeconds);
        // 修正typeof的语法
        o.MigrationsAssembly(Assembly.GetAssembly(typeof(AMSContext))!.FullName);
    });
    options.EnableSensitiveDataLogging();
});

方案2:添加设计时专用构造函数

在AMSContext中添加仅用于设计时的构造函数,传入模拟的ICurrentUser实现:

public partial class AMSContext : BaseContext
{
    private readonly ICurrentUser _currentUser;

    // 运行时构造函数
    public AMSContext(DbContextOptions<AMSContext> options, ICurrentUser currentUser) : base(options)
    {
        _currentUser = currentUser;
    }

    // 设计时构造函数
    public AMSContext() : base(new DbContextOptionsBuilder<AMSContext>()
        .UseSqlServer("你的数据库连接字符串")
        .Options)
    {
        _currentUser = new MockCurrentUser();
    }
}

// 模拟ICurrentUser实现
public class MockCurrentUser : ICurrentUser
{
    public int UserId => 1;
    // 实现接口其他成员,返回默认值即可
}

方案3:实现IDesignTimeDbContextFactory

创建工厂类专门处理设计时DbContext实例化:

public class AMSContextDesignTimeFactory : IDesignTimeDbContextFactory<AMSContext>
{
    public AMSContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<AMSContext>();
        optionsBuilder.UseSqlServer("你的数据库连接字符串", o =>
        {
            o.CommandTimeout((int)TimeSpan.FromMinutes(2).TotalSeconds);
            o.MigrationsAssembly(Assembly.GetAssembly(typeof(AMSContext))!.FullName);
        });

        return new AMSContext(optionsBuilder.Options, new MockCurrentUser());
    }
}

方案4:设计时注册模拟服务

在Program.cs中判断设计时环境,注册ICurrentUser的模拟实现:

var isDesignTime = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development" 
                   && Assembly.GetEntryAssembly()?.GetName().Name.Contains("DesignTime") == true;

services.AddScoped<ICurrentUser>(sp => 
{
    if (isDesignTime)
    {
        return new MockCurrentUser();
    }
    else
    {
        return new CurrentUserImplementation(); // 运行时真实实现
    }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 18:14:50