删除行时内存不足>;500000 EntityFramework 6

本文关键字:500000 EntityFramework gt 内存不足 删除行 | 更新日期: 2023-09-27 18:24:58

我有什么:

我有一个大的地址列表(ip地址)>数百万

我想做的事情:

通过EntityFramework 高效删除50万个地址

我的问题:

现在,我正在分成10000个地址的列表,并使用RemoveRange(ListOfaddresses)

if (addresses.Count() > 10000)
{
    var addressChunkList = extension.BreakIntoChunks<Address>(addresses.ToList(), 10000);
    foreach (var chunk in addressChunkList)
    {
        db.Address.RemoveRange(chunk);
    }
}

但我得到了一个OutOfMemoryException,这一定意味着即使我将地址划分为不同的列表,它也不会释放资源。

我该怎么办才能不得到OutOfMemoryException,并且仍然在合理的时间内删除大量地址?

删除行时内存不足>;500000 EntityFramework 6

当我需要做类似的事情时,我会使用以下插件(我没有关联)。

https://github.com/loresoft/EntityFramework.Extended

这允许您使用实体框架进行批量删除,而不必首先选择实体并将其加载到内存中,这当然更有效。

网站示例:

context.Users.Delete(u => u.FirstName == "firstname");

那么?你是从哪里知道EF是一种ETL/批量数据操作工具的?

事实并非如此。在一个事务中进行50万次删除将非常缓慢(一个接一个地删除),而EF并没有做到这一点。正如你所发现的。

你在这里无能为力。在设计参数范围内开始使用EF,或者为这种批量操作选择一种替代方法。在某些情况下,ORM没有什么意义。

几个建议。

  1. 使用存储过程或纯SQL
  2. 将您的DbContext移到更窄的范围:

    for (int i = 0; i < 500000; i += 1000)
    {
      using (var db = new DbContext())
      {
        var chunk = largeListOfAddress.Take(1000).Select(a => new Address { Id = a.Id });
        db.Address.RemoveRange(chunk);
        db.SaveChanges();
      }
    }
    

请参阅Rick Strahl关于批量插入的文章,了解更多详细信息