遍历 Linq-to-Entity IEnumerable 会导致内存不足异常
本文关键字:内存不足 异常 Linq-to-Entity IEnumerable 遍历 | 更新日期: 2023-09-27 18:30:57
我正在处理的代码部分收到一个
IEnumerable<T> items
其中每个项目都包含一个类,其属性反映 MSSQL 数据库表。
数据库表的行总数为 953664 行。代码中的数据集将筛选为一组 284360 行。
以下代码在进程达到大约 1,5 GB 内存分配时引发内存不足异常。
private static void Save<T>(IEnumerable<T> items, IList<IDataWriter> dataWriters, IEnumerable<PropertyColumn> columns) where T : MyTableClass
{
foreach (var item in items)
{
}
}
变量项的类型为
IQueryable<MyTableClass>
我找不到具有相同设置的任何人,我找到的其他解决方案在这里不适用。
我也尝试过分页,使用页面大小为 500 的 Skip 和 Take,但这只需要很长时间并最终得到相同的结果。似乎每次迭代后都不会释放对象。这是怎么回事?
如何重写此代码以处理更大的收集组?
好吧,正如 Servy 已经说过你没有提供你的代码,所以我会尝试做出一些预测......(对不起我的英语)
如果您在使用分页时在"foreach(项目中的变量项)"中有一个例外,那么我想,分页有问题。我写了几个例子来解释我的想法。
如果第一个示例,我建议您(仅用于测试)将过滤器放在保存功能中。
private static void Save<T>(IQueryable<T> items, IList<IDataWriter> dataWriters, IEnumerable<PropertyColumn> columns) where T : MyTableClass
{
int pageSize = 500; //Only 500 records will be loaded.
int currentStep = 0;
while (true)
{
//Here we create a new request into the database using our filter.
var tempList = items.Where(yourFilter).Skip(currentStep * pageSize).Take(pageSize);
foreach (var item in tempList)
{
//If you have an exception here maybe something wrong in your dataWriters or columns.
}
currentStep++;
if (tempList.Count() == 0) //No records have been loaded so we can leave.
break;
}
}
第二个示例演示如何在不对 Save 函数进行任何更改的情况下使用分页
int pageSize = 500;
int currentStep = 0;
while (true)
{
//Here we create a new request into the database using our filter.
var tempList = items.Where(yourFilter).Skip(currentStep * pageSize).Take(pageSize);
Save(tempList, dataWriters, columns); //Calling saving function.
currentStep++;
if (tempList.Count() == 0)
break;
}
尝试这两种方法,您要么解决您的问题,要么找到另一个提出异常的地方。
顺便说一下,另一个潜在的地方是你的数据作家。我想您在那里存储从数据库中收到的所有数据。也许您不应该保存所有数据?只需计算所有对象都需要的内存大小。
附言并且不要在代码中使用 while(true)。这只是一个例子:)