【问题标题】:How to use Linq to check if a string contains one of a subset of strings如何使用 Linq 检查字符串是否包含字符串子集之一
【发布时间】:2020-10-06 20:27:40
【问题描述】:

我有一个案例,允许用户在搜索用户名时提供一组关键字(更准确地说是子字符串)。

我有类似的东西

// this set of strings should find names such as john, mary or smith
List<string> searchStrings=new List<string>(){"jo","ma","th"}; 

// LINQ query looks like this

var filteredPatients=allPatients.Where(p =>
                            (searchStrings.Any(s=>p.Name.ToLower().Contains(s)));

但是这失败并给出了异常:

System.AggregateException :发生一个或多个错误。 (无法翻译 LINQ 表达式。要么以可翻译的形式重写查询,要么通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估/p>

这是针对 entityFramework、.NET Core 3.1 针对 Postgres Db 运行的

是否有另一种方法可以编写此查询以产生所需的结果?

注意:可以在 allPaitents 上调用 ToList() 或 ToArray(),但我想避免这种情况,因为整个(非常大的)表将被读入内存。

【问题讨论】:

  • 看起来你只是缺少一个右括号“)”..但这不应该让你出现那个错误..它甚至不应该编译..完整的代码是什么?
  • allPatients 可能是一个 IQueryable 或类似的延迟执行。试试allPatients.ToArray().Where...
  • @Thomas 是的,这是可能的,但这意味着我将整个表读入内存,我想避免。我会更新问题。

标签: c# entity-framework linq .net-core


【解决方案1】:

对于初学者,您需要一个PredicateBuilder,它允许您将表达式组合在一起。

使用它,您可以创建一个谓词单独搜索每个搜索字符串,然后将这些谓词组合在一起。

List<string> searchStrings = new List<string>() { "jo", "ma", "th" };

var predicate = searchStrings.Select<string, Expression<Func<Patient, bool>>>(search => patient => patient.Name.ToLower().Contains(search))
    .DefaultIfEmpty(patient => false) //or whatever else you want to do if there are no search strings
    .Aggregate(PredicateBuilder.Or);
            
var filteredPatients = allPatients.Where(predicate);

【讨论】:

    猜你喜欢
    • 2014-06-25
    • 2019-05-19
    • 2011-11-09
    • 2013-05-18
    • 1970-01-01
    • 2021-11-26
    • 2021-12-20
    • 1970-01-01
    • 2011-03-29
    相关资源
    最近更新 更多