例如我有一个像下面这样的类:
public class MasterRecord
{
public int Id { get; set; }
public string UniqueId{ get; set; }
}
public class DetailRecord
{
public int Id { get; set; }
public int MasterRecordId { get; set; }
public string UniqueId{ get; set; }
}
我还有2个列表,分别是:
MasterList和DetailList
MasterList将有大约300,000条记录, DetailList将有大约7,000,000条记录
我需要对主列表中的每个记录进行循环,并在DetailList中搜索具有相同名称的记录。
这是我的代码:
foreach (var item in MasterList)
{
var matchPersons = DetailList.Where(q => q.UniqueId == item .UniqueId).ToList();
if (matchPersons != null && matchPersons.Count() > 0)
{
foreach (var foundPerson in matchPersons)
{
//Do something with foundPerson
foundPerson.MasterRecordId = item.Id;
}
}
}
我的代码现在运行非常缓慢,每次搜索花费我500毫秒才能完成,因此,如果有300k条记录,则需要2500分钟:(来完成。 还有其他方法可以加快此功能吗? 感谢并原谅我的英语不好。
更新了代码,使我的工作更加清晰。
答案 0 :(得分:2)
使用某种哈希结构将是最好的选择之一:
name
如果键不存在,查找将返回空序列,因此您不必对其进行测试。
答案 1 :(得分:0)
您可以使用“加入名称”。
var result = masterList.Join(detailedList,m=>m.Name,d=>d.Name,(m,d)=>d);
答案 2 :(得分:0)
如果您需要处理“ MasterRecords及其DetailRecords”,请不要使用普通联接,而应使用GroupJoin。这将在内部创建类似于LookupTable的内容。
令人高兴的是,这也可以与数据库,CSV文件或用于获取记录的任何方法一起使用。您不必先将它们转换为列表。
// Your input sequences, if desired: use IQueryable
IEnumerable<MasterRecord> masterRecords = ...
IEnumerable<DetailRecord> detailRecords = ...
// Note: query not executed yet!
// GroupJoin these two sequences
var masterRecordsWithTheirDetailRecords = masterRecord.GroupJoin(detailRecords,
masterRecord => masterRecord.Id, // from masterRecord take the primary key
detailRecord => detailRecord.MasterRecordId // from detailRecord take the foreign key
// ResultSelector: from every MasterRecord with its matching DetailRecords select
(masterRecord, detailRecords) => new
{
// select the properties you plan to use:
Id = masterRecord.Id,
UniqueId = maserRecord.UniqueId,
...
DetailRecords = detailRecords.Select(detailRecord => new
{
// again: select only the properties you plan to use
Id = detailRecord.Id,
...
// not needed, you know the value:
// MasterRecordId = detailRecord.MasterRecordId,
}),
// Note: this is still an IEnumerable!
});
用法:
foreach(var masterRecord in masterRecordsWithTheirDetailRecords)
{
... // process the master record with its detail records
}
妙处是,您只需要处理一些MasterRecords (例如,在千分之一之后,您决定找到要搜索的内容), 或者,如果您有一些MasterRecords,而它们不需要所有的DetailRecords,则不会处理多余的记录。 Linq会解决这个问题