できるだけ単純化しました。これは、約3,000,000行のテーブルからの読み取りです。私は、データのいくつかの連結されたフィールドから辞書を作成したいと思います。ここで C#エンティティフレームワーク6:メモリが不足しているときに、メモリ不足になる可能性があります。
が私の意見では、これまでにメモリ不足の例外をスローすることはありません、コードです: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;
}
を私の意見では、バッチオブジェクトは、単純に割り当てられた各反復と前のメモリを交換する必要があります前のバッチオブジェクトはガベージコレクションされる必要があります。私は、この関数のループは、ほぼ静的な量のメモリを取る必要があります。最悪の場合、1行×10万のメモリが必要です。このテーブルの行の最大サイズは540バイトです。私はedmxからNavigation Propertiesを削除しました。
Entity Frameworkコンテキストは、データベースから読み取ったすべてのエンティティを追跡し、変更を追跡します。反復間のコンテキストを再作成してみてください。 – MarcinJuraszek
'AsNoTracking'を使ってトラッキングをオフにすることができます。フィルタリングされたIEnumerableのDbSet からforeachループを使用するのはなぜですか? 'Select ()' –
Igor
Thanks Igorを使用して、匿名タイプを使用して必要なものだけを返すことによっても助けることができます。それは今、完璧な意味があります。実際のコード(これは問題を特定するためのWTFコードです)では、返されたIQueryableをforeachで繰り返し、辞書に値を追加しています。実際のコードでは、ToList()は呼び出されません。私は、結果セットのToList()ではなく、コンテキスト内の変更トラッキングによって例外がスローされていることを認識していませんでした。 – urbadave