-1

我大约有 400,000 条来自文件的记录。但是在插入 30000 到 33000 条记录后,它会抛出错误“System.OutOfMemoryException”

在我的系统中,我有 8gb 的内存,我认为这已经足够了。我使用此代码一次插入一堆记录,例如 500 条记录。

this._context.AutoDetectChangesEnabled = false;

if(Counter % 500 == 0)
    _context.SaveChanges();

我尝试了所有可能的更改并进行了大量研发,并且还在此堆栈溢出站点上找到了所有可能的解决方案,但它无济于事。

我基本上在这种情况下使用 nopcommerce 使用

private readonly IDbContext context;

如果有任何困惑,也请告诉我!

public partial class EfRepository<T> : IRepository<T> where T : BaseEntity
{
      private IDbContext _context;
      private IDbSet<T> _entities;

      protected virtual IDbSet<T> Entities
      {
          get
          {
              if (_entities == null)
                  _entities = _context.Set<T>();
              return _entities;
          }
      }

      public virtual void Insert(IEnumerable<T> entities, bool enableTrackChanges = true)
        {
            try
            {
                if (entities == null)
                    throw new ArgumentNullException("entities");

                if(!enableTrackChanges)
                {
                    this._context.AutoDetectChangesEnabled = false;
                }

                foreach (var entity in entities)
                    this.Entities.Add(entity);

                this._context.SaveChanges();
            }
            catch (DbEntityValidationException dbEx)
            {
                throw new Exception(GetFullErrorText(dbEx), dbEx);
            }
            finally
            {
                if (!this._context.AutoDetectChangesEnabled)
                    this._context.AutoDetectChangesEnabled = true;
            }
        }
}
4

1 回答 1

4

您需要重新创建上下文以避免内存不足异常。内存会增加,直到实体框架无法处理,然后抛出异常。这是实体框架中的内存限制,因此它无助于在更好的计算机上运行。

这应该有效:

if(Counter % 500 == 0)
{
    _context.SaveChanges();
    _context = new ....();
}

有关使用 EF 插入多行的更多帮助,另请参阅此内容。 在实体框架中插入的最快方式

编辑:我很抱歉不清楚并且没有引用消息来源。.NET 中对象的限制是 2GB,数组在 64 位机器上可以更大,但 EF 上下文不能大于 2GB。并且当连续使用 EF 上下文时,内存使用量可能会迅速增加,直到达到限制。因此,为了释放内存,最好在插入多行数据时在一段时间后更新上下文。所以限制在 .NET 上,而不是在 EF 上,正如我之前错误所说的那样。

关于 EF 上下文: https ://msdn.microsoft.com/en-us/library/jj729737(v=vs.113).aspx

如何获取 >2gb 数组(也表示其他对象未更改) https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/gcallowverylargeobjects-element

关于 2GB 限制和更大数组的旧更长源: https ://blogs.msdn.microsoft.com/joshwil/2005/08/10/bigarrayt-getting-around-the-2gb-array-size-limit/

于 2017-08-23T07:41:51.423 回答