如何在EF5中使用大型数据集减少内存占用?

Hom*_*sey 7 c# entity-framework-5

我正在尝试从SQL Server中提取大型数据集(140万条记录)并转储到WinForms应用程序中的文件.我试图用分页来做这件事,所以我不会立刻在内存中占用太多,但是这个过程会继续增加内存占用量.大约25%通过,它占了600,000K.我在做错分页吗?我可以就如何保持内存使用量不断增长得到一些建议吗?

var query = (from organizations in ctxObj.Organizations
                 where organizations.org_type_cd == 1
                 orderby organizations.org_ID
                 select organizations);
int recordCount = query.Count();
int skipTo = 0;
int take = 1000;
if (recordCount > 0)
{
    while (skipTo < recordCount)
    {
        if (skipTo + take > recordCount) 
            take = recordCount - skipTo;

        foreach (Organization o in query.Skip(skipTo).Take(take))
        {
            writeRecord(o);
        }
        skipTo += take;
    }
}
Run Code Online (Sandbox Code Playgroud)

may*_*lle 8

对象上下文将保留在内存中的对象上,直到它被丢弃为止.我建议在每批之后处理上下文,以防止内存占用继续增长.

您也可以使用AsNoTracking()(http://msdn.microsoft.com/en-us/library/gg679352(v=vs.103).aspx),因为您没有保存回数据库.


P.B*_*key 5

摆脱分页和使用AsNoTracking.

测试代码

 static void Main(string[] args)
        {
            var sw = new Stopwatch();
            sw.Start();
            using (var context = new MyEntities())
            {
                var query = (from organizations in context.LargeSampleTable.AsNoTracking()
                             where organizations.ErrorID != null
                             orderby organizations.ErrorID
                             select organizations);//large sample table, 146994 rows

                foreach (MyObject o in query)
                {
                    writeRecord(o);
                }

            }
            sw.Stop();

            Console.WriteLine("Completed after: {0}", sw.Elapsed);
            Console.ReadLine();
        }

        private static void writeRecord(ApplicationErrorLog o)
        {
            ;
        }
Run Code Online (Sandbox Code Playgroud)

测试用例结果:

内存消耗减少: 96%
执行时间缩短: 50%

解释

由于显而易见的原因,AsNoTracking为内存使用带来了好处,我们在将它们加载到内存时不必维护对实体的引用.物体几乎可以立即被GC读取.结合惰性求值和AsNoTracking,不需要分页和上下文销毁.

虽然这是一次测试,但是大量的行和大多数外部因素的排除使得它成为一般情况的良好表示.