删除行时内存不足>;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,并且仍然在合理的时间内删除大量地址?
当我需要做类似的事情时,我会使用以下插件(我没有关联)。
https://github.com/loresoft/EntityFramework.Extended
这允许您使用实体框架进行批量删除,而不必首先选择实体并将其加载到内存中,这当然更有效。
网站示例:
context.Users.Delete(u => u.FirstName == "firstname");
那么?你是从哪里知道EF是一种ETL/批量数据操作工具的?
事实并非如此。在一个事务中进行50万次删除将非常缓慢(一个接一个地删除),而EF并没有做到这一点。正如你所发现的。
你在这里无能为力。在设计参数范围内开始使用EF,或者为这种批量操作选择一种替代方法。在某些情况下,ORM没有什么意义。
几个建议。
- 使用存储过程或纯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(); } }
请参阅Rick Strahl关于批量插入的文章,了解更多详细信息