2012-01-13 11 views
0

C#およびEntity Framework 3.5では、数百万のレコードを持つコンテキストがあります。これには約2 GBのRAMが必要です。私がSaveChanges()と呼ぶとすぐに、それは私の8 GM RAMを満たし始め、交換を開始します。Entity Framework 3.5:オブジェクトを別々のコンテキストで段階的に保存する

私はプロファイラを使用しましたが、メモリを浪費していたSQLクエリであることが判明しました。

今、バッチで保存したいのですが、問題が発生しています。

私はLocationsのコレクションを持っています(これには、コレクションのコレクションとサブコレクションがあります)。私はバッチで、それぞれに新しいコンテキストを割り当てることを分割すると、できるだけ早く私はcontext.AddToOrder(firstBatch)ALL場所がそうであるように、すべてのバッチが突然、彼らがOrderを持っていないにもかかわらず、実体状態Addedを持っています。これにより、Order -> Locationの関係が存在しないため、保存に失敗します。

私は元のコレクション内のすべてのオブジェクトがコンテキストのサブセットのみを追加すると、状態Addedになるのはなぜですか?

+0

すべてのメモリがアプリケーションで使用されていますか?またはおそらくそれはSQL Serverによって使用されました。 –

+0

すべてのSQLクエリ文字列はどこかで生成されなければならず、私はそれがRAMであると推測しています。トランザクションスコープを使用して、チャンクだけを保存するのはどうでしょうか? – linkerro

+0

これはSQLサーバーではなく、別のマシンです。トランザクションの範囲についてそれは多分可能性がありますが、私が最後に試したとき(数週間前)には、サーバー上に非常に多くの奇妙な設定が必要でした。再起動が必要で、今すぐサーバーを再起動することはできません。とにかく、活動モニタを見た後、SQLは実際にRAMを消費している間にまだ実行されていません。 – Halfgaar

答えて

2

私は数百万のレコードを持つコンテキストを持っています。これには約2 GBのRAMが必要です。

私はあなたがこの答えが嫌いではないことがわかりますが、それは簡単です。 しないでください。 EF、特にEFv1はこの準備ができていません。 EFは数十MBを処理するツールではありません。このような大きなデータセットには、他のツールを使用するか、独自のコンテキストを使用して複数の小さなチェンジセットに分割する必要があります。

SaveChangesに電話すると、EFはエンティティの変更を検出し、実行する文を準備するなど、その魔法を試みます。メモリリークが発生する可能性がありますが、GCのためにリリースされていないメモリが多くなることもあります。そのような場合、あなたの現在の問題とは何の関係もありません。

Btw。 EFは変更を単一のトランザクションで保存しようとします。したがって、1つのトランザクションで2GBを節約しようとすると、さらに多くのレベルで問題が発生する可能性があります。

+0

Addを呼び出すと、単一の場所だけでなくオブジェクトグラフのすべてが追加されるためです。したがって、あなたのロケーションにstuffのナビゲーションプロパティがある場合は、stuffも追加され、stuffにロケーションのナビゲーションコレクションがある場合は、そのロケーションもすべて追加されます。それを分けるのは簡単ではありません。すでに2GBの相互接続されたオブジェクトを持っている場合は動作しません。バッチでオブジェクトを処理し、そのバッチに存在するリレーションのみを構築する必要があります。 –

+0

私が知る限り、ある場所は 'もの'を通して他の場所にリンクする必要があります。 1つの場所とそれは完全に自己完結している必要があります。しかし、私は再度確認して確認します。 – Halfgaar

関連する問題