簡體   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