2012-11-21 47 views
1

我想知道,是否有一種優雅的方式來刪除泛型集合中的多個項目(在我的情況下,一個List<T>),而無需執行諸如在LINQ查詢中指定謂詞來查找項目刪除?刪除列表中的多個元素<T>

我正在做一些批處理,其中我用Record填充List<T>需要處理的對象類型。這個處理結束於每個對象被插入到數據庫中。除了建立列表,然後循環遍歷每個單獨的成員並處理/插入它之外,我想執行事務性批量插入,其中包含來自列表的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#中的效率?

任何幫助/建議/提示,非常感謝!

+0

什麼是類'Record'?它是一個自定義類還是'IDataRecord'? –

+0

它看起來像你抓的記錄都在列表的開頭。你爲什麼不用'Queue '來代替? – itsme86

+0

「記錄」是我用來說明概念的假設自定義類。 –

回答

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); 
} 
+1

我最好先創建批量大小的列表。 –

+0

@HamletHakobyan完全同意 –

1

MoreLINQBatch extension method,將允許你打電話

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

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

你不會需要打擾採取的東西出了listOfRecords的。