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

使用IDbContextFactory时出现ObjectDisposedException错误,如何解决?

错误原因及解决方案

错误原因

你遇到的System.ObjectDisposedException,本质是IQueryable的延迟执行特性导致的:

  • 你在using代码块内创建DbContext实例,并构建了查询返回IQueryable<AppUser>对象
  • using块结束时,DbContext会被自动调用Dispose()释放所有资源
  • 但IQueryable并不会立即执行数据库查询,它只是保存查询逻辑;实际执行(比如绑定到UI、调用ToList()等)是在using块外部进行的,此时DbContext已经被销毁,自然无法访问上下文实例,抛出异常。

你的完整代码

@inject IDbContextFactory<IdentityContext> _contextFactory

@code {
    IQueryable<AppUser> FilteredCountries
    {
        get
        {
            using (var context = _contextFactory.CreateDbContext())
            {
                var itemsQueryable = context.Set<AppUser>().AsQueryable();
    
                var result = itemsQueryable?.Where(c => c.AccessFailedCount <= maxMedals);
    
                if (!string.IsNullOrEmpty(nameFilter))
                {
                    result = result.Where(c => c.UserName.Contains(nameFilter));
                }
    
                if (minMedals > 0)
                {
                    result = result.Where(c => c.AccessFailedCount >= minMedals);
                }
    
                return result;
            }
        }
    }
}

修复方案

方案1:立即执行查询,返回内存集合(推荐)

将IQueryable转换为内存集合(比如List<AppUser>),在using块内部完成数据库查询操作,这样后续操作的是内存中的数据,不再依赖已被释放的DbContext:

@inject IDbContextFactory<IdentityContext> _contextFactory

@code {
    List<AppUser> FilteredCountries
    {
        get
        {
            using (var context = _contextFactory.CreateDbContext())
            {
                var itemsQueryable = context.Set<AppUser>().AsQueryable();
    
                var result = itemsQueryable?.Where(c => c.AccessFailedCount <= maxMedals);
    
                if (!string.IsNullOrEmpty(nameFilter))
                {
                    result = result.Where(c => c.UserName.Contains(nameFilter));
                }
    
                if (minMedals > 0)
                {
                    result = result.Where(c => c.AccessFailedCount >= minMedals);
                }
    
                // 立即执行查询,把结果加载到内存中
                return result?.ToList() ?? new List<AppUser>();
            }
        }
    }
}

方案2:在数据使用时创建并销毁DbContext(适合异步场景)

如果需要异步查询,或者希望在组件的生命周期内按需获取数据,可以将查询逻辑封装为异步方法,在需要数据的地方调用,确保DbContext在查询完成后再释放:

@inject IDbContextFactory<IdentityContext> _contextFactory

@code {
    List<AppUser> FilteredUsers { get; set; } = new List<AppUser>();

    async Task LoadFilteredUsersAsync()
    {
        using (var context = _contextFactory.CreateDbContext())
        {
            var itemsQueryable = context.Set<AppUser>().AsQueryable();
    
            var result = itemsQueryable?.Where(c => c.AccessFailedCount <= maxMedals);
    
            if (!string.IsNullOrEmpty(nameFilter))
            {
                result = result.Where(c => c.UserName.Contains(nameFilter));
            }
    
            if (minMedals > 0)
            {
                result = result.Where(c => c.AccessFailedCount >= minMedals);
            }
    
            FilteredUsers = await result?.ToListAsync() ?? new List<AppUser>();
        }
    }

    // 组件初始化时加载数据
    protected override async Task OnInitializedAsync()
    {
        await LoadFilteredUsersAsync();
    }

    // 过滤条件变化时重新加载数据
    async Task OnFilterChanged()
    {
        await LoadFilteredUsersAsync();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 15:53:12