运营商’||’ 不能应用于’lambda expression’和’lambda expression’类型的操作数

如何构造包含OR的LINQ WHERE子句?


我有一个对象列表,我想返回符合搜索条件的对象。

包含的对象有很多属性,只要符合条件,我想返回它:

 IEnumerable list; String keyword; ... var results = list.Where( (item => item.Name.Contains(keyword, StringComparison.CurrentCultureIgnoreCase)) || (item => item.Description.Contains(keyword, StringComparison.CurrentCultureIgnoreCase)) || (item => item.Description.Contains(keyword, StringComparison.CurrentCultureIgnoreCase)) || (item => item.ItemType.Contains(keyword, StringComparison.CurrentCultureIgnoreCase)) || (item => item.ItemID.ToString().StartsWith(keyword, StringComparison.CurrentCultureIgnoreCase)) || (items => items.Value.ToString().StartsWith(keyword, StringComparison.CurrentCultureIgnoreCase)) ); 

但是无法编译:

运营商’||’ 不能应用于’lambda expression’和’lambda expression’类型的操作数

如何构造包含OR的LINQ WHERE子句?

也可以看看

  • LINQ在哪里或过滤c#

只需在同一个lambda表达式中完成所有测试…

 IEnumerable list; String keyword; ... var results = list.Where( item => item.Name.Contains(keyword, StringComparison.CurrentCultureIgnoreCase) || item.Description.Contains(keyword, StringComparison.CurrentCultureIgnoreCase) || item.Description.Contains(keyword, StringComparison.CurrentCultureIgnoreCase) || item.ItemType.Contains(keyword, StringComparison.CurrentCultureIgnoreCase) || item.ItemID.ToString().StartsWith(keyword, StringComparison.CurrentCultureIgnoreCase) || items.Value.ToString().StartsWith(keyword, StringComparison.CurrentCultureIgnoreCase) ); 

您试图在单独的lambda表达式中表达不正确的每个条件。

您希望将所有表达式放在单个lambda表达式中:

 var results = list.Where(item => (item.Name.Contains(keyword, StringComparison.CurrentCultureIgnoreCase)) || (item.Description.Contains(keyword, StringComparison.CurrentCultureIgnoreCase)) || (item.Description.Contains(keyword, StringComparison.CurrentCultureIgnoreCase)) // and so on ); 

只是一种我认为有趣的不同方法; 如果你需要,它可以提供更具组合性的解决方案。 您可以使用为linq-to-objects修改的Predicate Builder版本。 像这样:

 var predicate = DelegatePredicateBuilder.False(); predicate.Or (x => x.Name.Contains(keyword)) .Or (x => x.Description.Contains(keyword)) .Or (x => x.ItemID.ToString().StartsWith(keyword)) .Or (...); // etc var results = list.Where(predicate); 

我已经修剪了一些样板代码,只是展示了这个想法的要点。

linq-to-objects谓词构建器来自Jon Skeet的回答。 此处发布的代码是为了完整性:

 public static class DelegatePredicateBuilder { public static Func True() { return f => true; } public static Func False() { return f => false; } public static Func Or(this Func expr1, Func expr2) { return t => expr1(t) || expr2(t); } public static Func And(this Func expr1, Func expr2) { return t => expr1(t) && expr2(t); } } 

你不能组合多个lambda,你想根据where子句中的条件的(或|| )组合构建一个布尔表达式:

 var results = list.Where( item => item.Name.Contains(keyword, StringComparison.CurrentCultureIgnoreCase)) || item.Description.Contains(keyword, StringComparison.CurrentCultureIgnoreCase)) 

尝试在每次比较中删除lambda声明……类似于:

var results = list.Where((item => item.Name.Contains(keyword,StringComparison.CurrentCultureIgnoreCase)|| item.Description.Contains(keyword,StringComparison.CurrentCultureIgnoreCase)|| item.Description.Contains(keyword,StringComparison.CurrentCultureIgnoreCase )|| item.ItemType.Contains(keyword,StringComparison.CurrentCultureIgnoreCase)|| item.ItemID.ToString()。StartsWith(keyword,StringComparison.CurrentCultureIgnoreCase)|| items.Value.ToString()。StartsWith(keyword,StringComparison.CurrentCultureIgnoreCase) ));