2012-11-21 3 views
1

LINQ 쿼리에서 항목을 찾기 위해 조건자를 지정하는 등의 작업을 수행하지 않고 제네릭 컬렉션 (내 경우에는 List<T>)에서 여러 항목을 제거하는 우아한 방법이 있습니까 궁금합니다. 지우는 것?목록에서 여러 요소 제거 <T>

처리해야 할 객체 유형이 RecordList<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

'Record'는 개념을 설명하기 위해 사용한 가상의 커스텀 클래스입니다. –

답변

3

:

foreach(var batch in listOfRecords.ToBatches(batchSize)) 
{ 
    DoProcessingStuffThatHappensBeforeInsert(batch); 
    InsertBatchOfRecords(batch); 
} 
+1

배치 크기의 목록을 처음 만드는 것이 좋습니다. –

+0

@HamletHakobyan이 완전히 동의합니다. –

1

MoreLINQ 당신이 당신은 listOfRecords에서 물건을 복용 귀찮게 필요하지 않을

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

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

호출 할 수 있도록 해주는 Batch extension method 있습니다. 당신은 일괄 적으로 입력 순서를 분할 할 수 있습니다

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; 
} 

확장 방법으로