2016-04-14 2 views
4

こんにちは仲間の開発者は、ブロブのLINQクエリリスト、メモリ使用量

私はLINQクエリを使用して、OracleデータベースにBLOB形式で格納されたXMLオブジェクトのリストのエクスポートを改善しようとしています。

悲しいことに、BLOBは非常に大きく、読んでいるとメモリ使用量は2GBまで増加します。私のfileSetオブジェクトはIQueryable<myRecord>オブジェクトです。 私は

foreach (var file in fileSet){...} 

var files = fileSet.ToList(); //This time the list is causing the memory load. 
foreach(file in files){...} 

var e = fileSet.AsEnumerable().GetEnumerator(); 
while(e.MoveNext()){...} 

を試してみました。しかし、私はリストに大きな記録を打つたびに、使用するRAMの上にあります。 エクスポートを作成するには、Buffer.BlockCopyを使用してコードを探していましたが、メモリ過充電のためにメモリ使用量を減らす方法や各ブロブを読み込む方法がある場合は、この方向に進むことはありません。

+0

処理中にブロブをロードする必要がありますか?それとも、ファイルセットのレコード定義にこのBLOBフィールドがあるためですか? –

+0

@SergeyLブロブが必要です。このソフトウェアはこれらのBLOBを読み込んでいて、xlsファイルにエクスポートしています。基本的にxmlです。 –

答えて

1

最後に、私はlinqを使ってメモリに何か光を当てることができなかったので、linqでファイルのIDを取得した後、OracleCommandを使ってxmlファイルをストリーミングしました。

using (var reader = cmd.ExecuteReader()) 
{ 
    while (reader.Read()) 
    { 
     var blob = reader.GetOracleLob(0); 
     var buffer = new byte[128]; 
     using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Write)) 
     { 
      blob.CopyTo(fs); 
     } 
    } 
} 
1

いくつかの解決策があります: 1)AsNoTracking()をクエリに追加します。

fileSet.AsNoTracking() or fileSet.AsNoTracking().Where(...) 

AsNoTracking()レコードがデータベースコンテキストにキャッシュされませんので、空きレコードにガベージコレクタを支援します。しかし、それがすぐには機能しないことがわかっているように、あなたはまだ消費されたメモリを局所的に増加させるかもしれません。

2)blobフィールドを含まないレコードの別の定義を作成し、それによってファイルのリストを取得するか、または選択式を使用してそれが役立つかもしれませんが、SQLへの変換方法を確認する必要があります

fileSet.AsNoTracking().Select(x=>new { x.Id, x.Name }) 

は次にブロブを取得し、あなたが明示的になり、各レコードを処理

var myblob = model.Database 
    .SqlQuery<string>("select myblob from mytable where [email protected]", 
     new SqlParameter("@id", System.Data.SqlDbType.Int) { Value = myId }) 
    .FirstOrDefault(); 

または

var myBlob = fileSet 
     .AsNoTracking() 
     .Select(x=>new { x.Blob) 
     .FirstOrDefault(x=>x.ConfigId=myId); 
+0

答えのタンク。 私はまだEF 4.0上にいるので、私は 'AsNoTracking()'にアクセスしていません だから私は 'fileSet.SetMergeOption(MergeOption.NoTracking);を試みました しかしそれでも結果は変わりませんでした大きなBLOBを持つオブジェクトがロードされた後のメモリ使用量。 しかし、私はこのことについて引き続き検索し、私のマネージャーがOKならばEFを更新するかもしれません^^ –