繁体   English   中英

C#实体框架6:绝对不应该用完内存时

[英]C# Entity Framework 6: Out Of Memory when it absolutely should not run out of memory

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

我认为以下代码永远不会抛出“内存不足”异常:

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中删除了导航属性。

您可以使用AsNoTracking关闭跟踪。 为什么不在DbSet的已过滤IEnumerable上使用foreach循环? 您也可以通过使用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#如何理解应该清除哪些内容以分配新的内存。

批处理是一个查询,不包含任何内容。 调用.ToList()后,它将执行查询并返回记录。

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

        skip += take;
        batch = context.VarsHG19.OrderBy(v => v.Id).Skip(skip).Take(take).ToList();
    }

    return 1;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM