C#实体框架6:绝对不应该用完内存时 [英] C# Entity Framework 6: Out Of Memory when it absolutely should not run out of memory

查看:77
本文介绍了C#实体框架6:绝对不应该用完内存时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已尽可能简化了事情.这是从具有约3,000,000行的表中读取的.我想从数据的某些串联字段中创建一个Dictionary.

I've simplified things as much as possible. This is reading from a table that has around 3,000,000 rows. I want to create a Dictionary from some concatenated fields of the data.

在我看来,这是永远不应该抛出内存不足异常的代码:

Here's the code that, in my opinion, should never, ever throw an Out Of Memory Exception:

public int StupidFunction()
{
    var context = GetContext();
    int skip = 0;
    int take = 100000;
    var batch = context.VarsHG19.OrderBy(v => v.Id).Skip(skip).Take(take);
    while (batch.Any())
    {
        batch.ToList();
        skip += take;
        batch = context.VarsHG19.OrderBy(v => v.Id).Skip(skip).Take(take);
    }

    return 1;
}

在我看来,应该在每次迭代时简单地替换批处理对象,并且应该对垃圾回收分配给前一个批处理对象的先前内存.我希望此函数中的循环应该占用几乎静态的内存.在最坏的情况下,它应该受一行的内存需求* 100,000的限制.该表中一行的最大大小为540字节.我从edmx中删除了导航属性.

In my opinion, the batch object should simply be replaced each iteration and the previous memory allocated for the previous batch object should be garbage collected. I would expect that the loop in this function should take a nearly static amount of memory. At the very worst, it should be bounded by the memory needs of one row * 100,000. The Max size of a row from this table is 540 bytes. I removed Navigation Properties from the edmx.

推荐答案

您可以使用AsNoTracking关闭跟踪.为什么不在DbSet中经过过滤的IEnumerable上使用foreach循环?您也可以通过使用Select()– Igor

You can turn off tracking using AsNoTracking. Why not use a foreach loop though on a filtered IEnumerable from the DbSet? You can also help by only returning what you need using an anonymous type using Select() – Igor

感谢答案伊戈尔.

public int StupidFunction()
{
    var context = GetContext();
    int skip = 0;
    int take = 100000;
    var batch = context.VarsHG19.AsNoTracking().OrderBy(v => v.Id).Skip(skip).Take(take);
    while (batch.Any())
    {
        batch.ToList();
        skip += take;
        batch = context.VarsHG19.AsNoTracking().OrderBy(v => v.Id).Skip(skip).Take(take);
    }

    return 1;
}

没有内存不足异常.

这篇关于C#实体框架6:绝对不应该用完内存时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆