迭代Linq-to-Entities IEnumerable导致OutOfMemoryException

时间:2016-01-19 16:46:02

标签: c# sql-server entity-framework linq-to-entities

我正在处理的代码部分收到了

IEnumerable<T> items 

其中每个项目都包含一个具有反映MSSQL数据库表的属性的类。

数据库表的总计数为953664行。 代码中的数据集被过滤到一组284360行。

当进程达到大约1.5 GB内存分配时,以下代码抛出OutOfMemoryException。

 private static void Save<T>(IEnumerable<T> items, IList<IDataWriter> dataWriters, IEnumerable<PropertyColumn> columns) where T : MyTableClass
    {
        foreach (var item in items)
        {
        }
    }

变量的类型为

IQueryable<MyTableClass>

我找不到任何具有相同设置的人,而我发现的其他解决方案不适用于此处。

我也尝试过分页,使用Skip和Take,页面大小为500,但这需要很长时间才能得到相同的结果。似乎每次迭代后都没有释放对象。那怎么样?

如何重写此代码以应对更大的收藏集?

1 个答案:

答案 0 :(得分:0)

好吧,正如Servy已经说过你没有提供你的代码所以我会尝试做一些预测...(对不起我的英文)

如果在使用分页时“foreach(项目中的var项目)”中有异常,那么我猜,分页有问题。我写了几个例子来解释我的想法。

如果第一个例子我建议你(仅用于测试)将你的过滤器放在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;
}

第二个示例显示如何在保存功能

中没有任何更改的情况下使用分页
{{1}}

尝试这两种方法,您既可以解决问题,也可以找到引发异常的其他地方。

顺便说一句,另一个潜在的地方是你的datawriters。我想你存储了从数据库收到的所有数据。也许你不应该保存所有数据?只需计算所有对象都需要的内存大小。

P.S。并且不要在代码中使用while(true)。这只是一个例子:)