C# 迭代大型数据集时OutOfMemoryException

C# 迭代大型数据集时OutOfMemoryException,c#,.net,memory,C#,.net,Memory,我有一张大约100000行的桌子(而且它会越来越大) 我的代码现在抛出了一个OutOfMemoryException,当我在循环中得到大约80000条记录时(尽管我的系统当时有超过10gb的空闲空间,但看起来visual studio限制在1.5gb左右) 该代码旨在循环所有记录,并仅检查某些条件。我拿出实际处理记录的代码,内存仍然充满 using (var db = new PlaceDBContext()) { Messages.Output("Total: " + db.Compa

我有一张大约100000行的桌子(而且它会越来越大)

我的代码现在抛出了一个
OutOfMemoryException
,当我在循环中得到大约80000条记录时(尽管我的系统当时有超过10gb的空闲空间,但看起来visual studio限制在1.5gb左右)

该代码旨在循环所有记录,并仅检查某些条件。我拿出实际处理记录的代码,内存仍然充满

using (var db = new PlaceDBContext())
{
    Messages.Output("Total: " + db.Companies.Count());
    int count = 0;
    foreach (var company in db.Companies)
    {

        // I am not actually doing anything here,
        // I took out my code and the memory still fills up
        // CheckMatchConditions(company);

        count++;

        Console.SetCursorPosition(0, Console.CursorTop);
        Console.Write(count.ToString() + "          ");

    }

}
我认为这可能与保持上下文打开有关,因此我对代码进行了重构,一次只获取1000条记录,并首先将它们全部枚举到一个列表中。这就是我想到的:

int count = 0;
int total = 0;
using (var db = new PlaceDBContext())
{
    Messages.Output("Total: " + db.Companies.Count());
    total = db.Companies.Count();
}
while (count < total)
{
    List<Company> toMatch = new List<Company>();
    using (var db = new PlaceDBContext())
    {
        toMatch = db.Companies.Include(x => x.CompaniesHouseRecords).OrderBy(x => x.ID).Skip(count).Take(1000).ToList();
    }

    foreach (var company in toMatch)
    {

        // CheckMatchConditions(company);

        count++;

        Console.SetCursorPosition(0, Console.CursorTop);
        Console.Write(count.ToString() + "          ");

    }
}
int count=0;
int-total=0;
使用(var db=new PlaceDBContext())
{
Messages.Output(“总计:+db.companys.Count());
总计=db.companys.Count();
}
而(计数<总数)
{
List toMatch=新列表();
使用(var db=new PlaceDBContext())
{
toMatch=db.companys.Include(x=>x.companyeshousecords).OrderBy(x=>x.ID).Skip(count).Take(1000).ToList();
}
foreach(托马奇的var公司)
{
//检查匹配条件(公司);
计数++;
Console.SetCursorPosition(0,Console.CursorTop);
Console.Write(count.ToString()+);
}
}
这样做的速度要慢得多,但仍然会以大约相同的循环记录速率填充内存

当我注释掉我的实际方法时,它必须是这些
toMatch
列表在内存中挥之不去

我在这里不知所措,有人能告诉我应该如何管理内存吗?

添加。()这确保DbContext不会跟踪实体

using (var db = new PlaceDBContext())
{
    Messages.Output("Total: " + db.Companies.Count());
    int count = 0;
    foreach (var company in db.Companies.AsNoTracking())
    {
        count++;
        Console.SetCursorPosition(0, Console.CursorTop);
        Console.Write(count.ToString() + ". company : " + company.someProp);
    }
}

不要迭代对象集合,因为在对象中选择实体后,EF跟踪会发生更改。 迭代一些DTO

db.Companies.Select(c => new CompanyDto{ Name = c.Name});

但最好不要遍历整个数据收集。请尝试在LINQ中编写检查条件方法,以允许SQL server进行筛选。

能否将匹配条件转换为where条件?类似于db.companys.Where(检查匹配条件)。。您是否希望以某种方式处理对象?如果是,怎么做?太好了!内存现在没有超过60mb