1

List<T>疑問に思っていたのですが、LINQクエリで述語を指定して削除するアイテムを見つけるなどの操作を行わずに、ジェネリックコレクション(私の場合は)から複数のアイテムを削除するエレガントな方法はありますか?

私は少しのバッチ処理を行っています。そこでは、処理する必要のあるオブジェクトタイプをでList<T>埋めています。Recordこの処理は、各オブジェクトがデータベースに挿入されることで終了します。リストを作成し、個々のメンバーをループして処理/挿入する代わりに、Nリソースをあまり消費しないため、リストのアイテムのグループを使用してトランザクションの一括挿入を実行したいと思います(ここで、は構成ファイルに入れることができるものをN表します) BatchSize、または同等のもの)。

私は次のようなことをしたいと思っています:

public void ProcessRecords()
{
    // list of Records will be a collection of List<Record>
    var listOfRecords = GetListOfRecordsFromDb( _connectionString );
    var batchSize = Convert.ToInt32( ConfigurationManager.AppSettings["BatchSize"] );

    do
    {
       var recordSubset = listOfRecords.Take(batchSize);
       DoProcessingStuffThatHappensBeforeInsert( recordSubset );

       InsertBatchOfRecords( recordSubset );

       // now I want to remove the objects added to recordSubset from the original list
       // the size of listOfRecords afterwards should be listOfRecords.Count - batchSize
    } while( listOfRecords.Any() )
}

サブセットを繰り返し処理して次のような項目を削除するのではなく、これを一度に実行する方法を探しています。

foreach(Record rec in recordSubset)
{
   if( listOfRecords.Contains(rec) ) 
   { 
      listOfRecords.Remove(rec);
   }
}

の使用を検討していましList.RemoveRange( batchSize )たが、最初にStackOverflowのフィードバックを取得したいと思いました:) C#でのバッチ処理アルゴリズムの効率を最大化するためにどのような方法を使用しますか?

ヘルプ/提案/ヒントは大歓迎です!

4

2 に答える 2

3

延長方法あり

public static IEnumerable<List<T>> ToBatches<T>(this List<T> list, int batchSize)
{
    int index = 0;
    List<T> batch = new List<T>(batchSize);

    foreach (T item in list)
    {
        batch.Add(item);    
        index++;

        if (index == batchSize)
        {
            index = 0;                
            yield return batch;
            batch = new List<T>(batchSize);
        }
    }

    yield return batch;
}

入力シーケンスをバッチに分割できます。

foreach(var batch in listOfRecords.ToBatches(batchSize))
{
   DoProcessingStuffThatHappensBeforeInsert(batch);
   InsertBatchOfRecords(batch);
}
于 2012-11-21T16:46:11.810 に答える
1

MoreLINQには、次の呼び出しを可能にするBatch拡張メソッドがあります。

var listOfRecords = GetListOfRecordsFromDb( _connectionString );
var batchSize = Convert.ToInt32( ConfigurationManager.AppSettings["BatchSize"] );

foreach(var batch in listOfRecords.Batch(batchSize))
{
   DoProcessingStuffThatHappensBeforeInsert(batch);
   InsertBatchOfRecords(batch);
}

から物をわざわざ取り出す必要はありませんlistOfRecords

于 2012-11-21T16:44:54.570 に答える