Resharper说要把foreach转换成LINQ,但这可能吗?

本文关键字:LINQ foreach 转换 Resharper | 更新日期: 2023-09-27 18:03:23

我有一个Project实体,它有一个导航属性,它是一个地址列表。在搜索页面上,我允许用户一次按多个地址搜索项目。是否可以在单个语句中做到这一点,或者我需要循环遍历搜索的地址?

目前我有以下代码,其中searchedAddresses是用于搜索项目的地址列表。在foreach循环中,我创建了一个查询,并在每次循环中将其与整个查询联合起来。Resharper说foreach可以用LINQ重写,如果可能的话,我想摆脱查询的联合。

foreach (AddressModel address in searchedAddresses)
{
    var query = _projectRepository.Get().Where(p => p.Addresses.Any(a => a.StreetName.ToLower().StartsWith(address.StreetName.ToLower())));
    union = (union == null ? query : union.Union(query));
}

我试着把它写成一个语句,但它不起作用:

var query = _projectRepository.Get().Where(p => p.Addresses.Any(a => searchedAddresses.Any(sa => a.StreetName.ToLower().StartsWith(sa.StreetName.ToLower())));

当我这样做的时候,我得到以下错误:"无法创建类型' epec . webapi . models . addressmodel '的常量值。在此上下文中只支持基本类型或枚举类型。"

我假设这是因为searchedAddresses.Any()部分。有人知道如何编写这个查询,以便我不需要遍历地址和联合查询吗?或者这是一件可以做的事情?

谢谢!

编辑:在我最初忘记的第二个查询中添加了ToLower和StartsWith。

Resharper说要把foreach转换成LINQ,但这可能吗?

我想最简单的方法是为您首先搜索的街道名称创建一个List<string> -我希望这些名称是可转换的:

var searchedStreets = searchedAddresses.Select(x => x.StreetName).ToList();
var query = projectRepository
      .Get()
      .Where(p => p.Addresses.Any(a => searchStreets.Contains(a.StreetName)));

如果List<string>不起作用,可能值得尝试string[]。(把ToList改成ToArray)

我怀疑ReSharper想让你做这样的事情:

var union = searchedAddresses
    .Select(address => _projectRepository.Get()
        .Where(p => p.Addresses.Any(a =>
            a.StreetName.ToLower().StartsWith(address.StreetName.ToLower()))))
    .Aggregate(
        (something)null,
        (union, query) => union.Union(query));

在原始代码中somethingunion类型相同。

(如果它告诉你可以将循环转换为单个查询,它应该也会给你自动执行的选项)

我不认为这是特别干净的。

当您必须像这样"合并"给定集合的所有结果时,您可以用SelectMany语句替换Foreach语句;

searchedAddresses
    .SelectMany(address =>
        _projectRepository
        .Get()
        .Where(p => p.Addresses.Any(a => 
            a.StreetName
            .ToLower()
            .StartsWith(address.StreetName.ToLower()))))
    .Distinct();

这将遍历每个结果,与合并每个子查询

产生相同的效果(可能会提高性能)

编辑:当我复制/粘贴你的问题代码时,使用了错误的lambda参数。固定。编辑:与Union不同,SelectMany不删除重复项,因此我相应地更新了代码