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

使用EF Core批量插入百万条数据时内存不足异常的解决方法

修复EF Core批量插入内存不足异常的最优方法

核心问题分析

当前代码通过AsEnumerable()把stagingUnits全量加载到内存,同时创建百万个ImportJobValidation对象存入List后一次性提交,导致内存被大量对象占满,触发内存溢出异常。

最优解决方案:分批处理+优化匹配逻辑

  • 第一步:优化错误匹配逻辑
    把errors集合转成以StagingId为键的HashSet,避免每次判断都遍历整个errors列表,既减少内存占用又提升匹配效率:

    var errorStagingIds = new HashSet<int>(errors.Select(e => e.StagingId));
    
  • 第二步:分批读取并插入数据
    不要全量加载stagingUnits,而是用EF Core分页查询,每次处理固定数量的记录(比如1000条,可根据内存情况调整),处理完一批就提交并清理上下文,释放内存:

    var batchSize = 1000;
    var totalCount = await stagingUnits.CountAsync();
    var batchCount = (int)Math.Ceiling((double)totalCount / batchSize);
    
    var errorStagingIds = new HashSet<int>(errors.Select(e => e.StagingId));
    
    for (int i = 0; i < batchCount; i++)
    {
        var currentBatch = await stagingUnits
            .Skip(i * batchSize)
            .Take(batchSize)
            .ToListAsync();
    
        var importJobValidations = currentBatch.Select(stg => new ImportJobValidation
        {
            Guid = Guid.NewGuid(),
            StudyProductStagingID = stg.Id,
            IsValidationSuccessful = !errorStagingIds.Contains(stg.Id),
            Type = "UPLOAD",
            IsActive = true,
            CreatedBy = userId,
            CreatedOn = DateTime.UtcNow
        }).ToList();
    
        await _supplyManagementHangFireContext.AddRangeAsync(importJobValidations);
        await _supplyManagementHangFireContext.SaveChangesAsync();
    
        // 清理上下文,避免跟踪过多实体占用内存
        _supplyManagementHangFireContext.ChangeTracker.Clear();
    }
    
  • 额外优化:使用无跟踪查询
    如果stagingUnits不需要被上下文跟踪,可加上AsNoTracking()进一步减少内存占用:

    var currentBatch = await stagingUnits
        .AsNoTracking()
        .Skip(i * batchSize)
        .Take(batchSize)
        .ToListAsync();
    

方案优势

  1. 分批处理仅在内存中保留少量数据,从根源上避免内存溢出;
  2. HashSet将匹配操作的时间复杂度从O(n)降到O(1),提升整体执行效率;
  3. 清理上下文跟踪的实体,避免上下文积累大量未释放的对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 10:17:11