通过字符串C#在很大的列表中搜索对象的最快方法

时间:2019-03-04 05:09:57

标签: c# linq search

例如我有一个像下面这样的类:

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分钟:(来完成。 还有其他方法可以加快此功能吗? 感谢并原谅我的英语不好。

更新了代码,使我的工作更加清晰。

3 个答案:

答案 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会解决这个问题