是否有更优化的LINQ to Objects搜索方式?

时间:2014-11-12 02:54:03

标签: c# linq

给出以下DTO和LINQ查询:

public class DupeCheckRecordsDto
{
    public string A_HOMEPHONE_ { get; set; }
    public string A_WORKPHONE_ { get; set; }
    public string A_MOBILEPHONE_ { get; set; }
    public string A_SSNO_ { get; set; }
    public string A_EMAILADDRESS_ { get; set; }
}


var phones =
    new[]
    {
        leadApplication.CellPhone,
        leadApplication.DayPhone,
        leadApplication.EveningPhone,
        leadApplication.OtherPhone
    };

List<DupeCheckRecordsDto> listOfDays = _backEndRepository.DupeCheckRecords(daysBack).ToList();

bool matchFound = false;

foreach (var phone in phones)
{
    bool result = listOfDays.Any(p => p.A_HOMEPHONE_ == phone || p.A_MOBILEPHONE_ == phone || p.A_WORKPHONE_ == phone);
    if (!result) continue;
    matchFound = true; 
    break;
}

listOfDays的实现很快,所以我不在那里寻找优化,它是Any的使用和与我有关的循环结构。

谢谢你, 斯蒂芬

3 个答案:

答案 0 :(得分:3)

是。改变这个:

var phones =
    new[]
    {
        leadApplication.CellPhone,
        leadApplication.DayPhone,
        leadApplication.EveningPhone,
        leadApplication.OtherPhone
    };

要:

var phones = new HashSet<string>
    {
        leadApplication.CellPhone,
        leadApplication.DayPhone,
        leadApplication.EveningPhone,
        leadApplication.OtherPhone
    };

然后您的LINQ查询变为:

bool result = listOfDays.Any(p => phones.Contains(p.A_HOMEPHONE)
    || phones.Contains(p.A_MOBILEPHONE)
    || phones.Contains(p.A_WORKPHONE_));

您不需要foreach (var phone in phones)。以上将在一次通过中搜索所有四个。

这里的要点是你只需要扫描列表。 HashSet.Contains是O(1)操作。因此,您只需查看一次记录。

在原版中,你会四次查看每条记录。

如果您将phones作为数组,则phones.Contains必须与列表中的每个项目进行比较。使用HashSet,它只进行一次查找。

有多快会有点不清楚,因为phones列表有点小。

答案 1 :(得分:1)

这是一种消除foreach语法的方法,但我希望它的表现大致相同。

bool matchFound = listOfDays.Any(p =>
  phones.Contains(p.A_HOMEPHONE_) || 
  phones.Contains(p.A_MOBILEPHONE) ||
  phones.Contains(p.A_WORKPHONE_));

答案 2 :(得分:1)

怎么样:

 bool matchFound = listOfDays.Any(p => phones.Any(phone=> p.A_HOMEPHONE_ == phone || p.A_MOBILEPHONE_ == phone || p.A_WORKPHONE_ == phone));

 bool matchFound = listOfDays.Any(p => phones.Contains(p.A_HOMEPHONE_) ||phones.Contains(p.A_MOBILEPHONE_) ||phones.Contains(p.A_WORKPHONE_ ));