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

.NET Core 2批量创建用户时出现ObjectDisposed异常求助

解决EF Core初始化循环创建用户时的ObjectDisposedException问题

嘿,这个问题我之前踩过坑!大概率是DbContext的生命周期没管好——你的_context在循环过程中被提前释放了,所以第一个用户创建完,后面的操作都拿不到可用的上下文了。结合你说的只有第一个用户成功的现象,给你几个靠谱的解决方案:

方案1:把异步操作的await做足,别让上下文提前“下班”

先检查你调用Initialize方法的地方有没有加await!如果调用时直接写dbInitializer.Initialize()而不是await dbInitializer.Initialize(),那整个初始化过程会变成“火急火燎”的异步操作,包含_context的作用域可能在初始化完成前就被回收了,这是最常见的原因。

然后看Initialize方法内部,添加用户时要确保每个异步操作都正确await,或者干脆批量添加更高效:

public async Task Initialize()
{
    _context.Database.EnsureCreated();
    // 先检查有没有用户,避免重复初始化
    if (!_context.Users.Any())
    {
        // 先把5个用户都定义好
        var initialUsers = new List<User>
        {
            new User { UserName = "Admin", Email = "admin@example.com" },
            new User { UserName = "User1", Email = "user1@example.com" },
            new User { UserName = "User2", Email = "user2@example.com" },
            new User { UserName = "User3", Email = "user3@example.com" },
            new User { UserName = "User4", Email = "user4@example.com" }
        };
        
        // 批量添加,只调用一次SaveChangesAsync
        _context.Users.AddRange(initialUsers);
        await _context.SaveChangesAsync();
        
        // 如果你非要循环逐个添加,记得每个SaveChangesAsync都要await
        // foreach (var user in initialUsers)
        // {
        //     _context.Users.Add(user);
        //     await _context.SaveChangesAsync();
        // }
    }
}

批量添加不仅能减少数据库操作次数,还能避免循环中多次调用异步方法可能带来的上下文状态问题。

方案2:用作用域隔离DbContext(适合依赖注入场景)

如果你的DbInitialize是单例服务,但DbContext注册的是Scoped生命周期,那单例持有Scoped的上下文肯定会出问题——上下文会被提前回收或者状态混乱。这种情况下,应该在初始化方法里自己创建一个作用域来获取上下文:

private readonly IServiceProvider _serviceProvider;

// 构造函数注入IServiceProvider
public DbInitialize(IServiceProvider serviceProvider)
{
    _serviceProvider = serviceProvider;
}

public async Task Initialize()
{
    // 创建一个新的作用域,确保上下文在这个作用域内存活
    using var scope = _serviceProvider.CreateScope();
    var context = scope.ServiceProvider.GetRequiredService<YourDbContext>();
    
    context.Database.EnsureCreated();
    if (!context.Users.Any())
    {
        var initialUsers = new List<User>
        {
            // 5个用户的定义
        };
        context.Users.AddRange(initialUsers);
        await context.SaveChangesAsync();
    }
}

这种方式相当于每次初始化都用一个全新的、生命周期完全受控的DbContext,从根源上避免了上下文被意外释放的问题。

方案3:排查是否有其他代码偷偷Dispose了上下文

检查项目里有没有其他地方(比如中间件、全局过滤器、自定义的DbContext包装类)提前调用了_context.Dispose(),或者依赖注入容器的配置错了——比如把DbContext注册成了Transient,而你的初始化服务是单例,那第一次用上下文之后,容器就可能把它回收了。

最后再确认下注册机制的禁用

确保你已经彻底禁用了标准注册,比如用Identity的话,可以这么配置:

services.AddDefaultIdentity<User>(options => options.SignIn.RequireConfirmedAccount = false)
    .AddEntityFrameworkStores<YourDbContext>();

// 禁用注册页面和相关API
services.AddRazorPagesOptions(options =>
{
    // 把登录页设为默认页
    options.Conventions.AddPageRoute("/Account/Login", "");
    // 给注册页加授权,或者直接移除
    options.Conventions.AuthorizePage("/Account/Register");
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:01:49