我想知道,是否有一种优雅的方法可以从泛型集合中移除多个项目(在我的情况下,是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#中批处理算法的效率?
非常感谢任何帮助/建议/提示!
答案 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 :(得分:1)
MoreLINQ有一个Batch
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
中取出内容。