Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 删除行时内存不足>;500000实体框架6 我得到的是:_C#_Entity Framework_Out Of Memory - Fatal编程技术网

C# 删除行时内存不足>;500000实体框架6 我得到的是:

C# 删除行时内存不足>;500000实体框架6 我得到的是:,c#,entity-framework,out-of-memory,C#,Entity Framework,Out Of Memory,我有一个庞大的地址列表(ip地址)>数百万 我想做的是: 通过EntityFramework高效地删除500k地址 我的问题是: 现在,我正在拆分成10000个地址的列表,并使用RemoveRange(ListoFaddress) if(addresses.Count()>10000) { var addressChunkList=extension.breakintockhunks(addresses.ToList(),10000); foreach(addressChunkList中的变量块

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

我想做的是: 通过EntityFramework高效地删除500k地址

我的问题是: 现在,我正在拆分成10000个地址的列表,并使用RemoveRange(ListoFaddress)

if(addresses.Count()>10000)
{
var addressChunkList=extension.breakintockhunks(addresses.ToList(),10000);
foreach(addressChunkList中的变量块)
{
db.Address.RemoveRange(块);
}
}
但是我得到了一个
OutOfMemoryException
,这意味着即使我将地址拆分为单独的列表,也不能释放资源


我该怎么做才能不让OutOfMemoryException在合理的时间内删除大量的地址呢?您是从哪里想到EF是一个ETL/批量数据操作工具的

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


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

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

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

网站上的示例:

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

一些建议

  • 使用存储过程或普通SQL
  • 将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();
      }
    }
    
    for(int i=0;i<500000;i+=1000)
    {
    使用(var db=new DbContext())
    {
    var chunk=largeListOfAddress.Take(1000).Select(a=>newaddress{Id=a.Id});
    db.Address.RemoveRange(块);
    db.SaveChanges();
    }
    }
    

  • 请参见

    我刚刚想到,当我试图保存更改()时会引发异常;使用更小的块?试着用5000、2500、1250。。。。1直到异常消失为止?当地址空间接近100000个地址时,即使没有拆分成更小的块,也没有问题。编写SQL来实现这一点可能更容易吗?我认为您试图使用错误的工具进行作业。FWIW EF 7应该支持批处理操作(虽然在7.0中不一定),但我没有,我只是通过尝试和错误来学习限制-有人做了一个bulkInsert,实际上在几秒钟内插入了一百万行-所以我想继续并尝试删除。好的,bulkInsert通过绕过efcore工作(我知道,我也这么做)。但是,100万行删除对服务器来说也是一个很大的负担;)SQL Server通常更适合插入和选择。@BenjaminPaul否,抱歉。扩展库未使用EF-它绕过了完整的EF功能。是的,它是有效的,但它不是“使用EF”。Jsut,因为有人为EF DbContext编写和扩展方法并没有使其“使用EF”。批量删除forexmaple与加载的实体完全正交,不更新它们。并不是说它没用——这是一个很好的方法——但EF集成只是为了保持一个“可见的API”而装模作样。@TomTom我完全知道它没有使用你所说的“EF”,你不需要向我解释。然而,它所做的是共享相同的语法,并增加了许多便利性。也许我们对这个问题的解释不同,我假设用户正在寻找一种使用他熟悉的语法进行批量删除的方法。。。尽管如此,我们不必如此对抗,我们都在学习,伙计。减少一些时间。这实际上比创建行更快-刚刚测试了100万行,创建大约需要4秒,删除大约需要3秒+1我同意该解决方案需要考虑作业的最佳工具,但这是一个非常有趣的项目。谢谢
    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();
      }
    }