删除行时的OutOfMemory> 500000 EntityFramework 6

时间:2014-09-29 08:20:42

标签: c# entity-framework out-of-memory

我得到了什么:

我有一大堆地址(ip addr)>数以百万计

我想做的事情:

通过EntityFramework

有效删除500k地址

我的问题:

现在,我将拆分为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并仍然在合理的时间内删除大量地址,我该怎么办?

3 个答案:

答案 0 :(得分:4)

所以?您是否了解EF是ETL /批量数据处理工具?

不是。在一个事务中执行50万次删除将会死得很慢(逐个删除),EF就是这样做的。你发现了。

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

答案 1 :(得分:4)

当我需要做类似的事情时,我转向了以下插件(我没有关联)。

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

这允许您使用Entity Framework进行批量删除,而无需先选择并将实体加载到内存中,这当然更有效。

网站上的示例:

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

答案 2 :(得分:1)

一些建议。

  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();
      }
    }
    
  3. 请参阅Rick Strahl's post on bulk inserts for more details