运营商’||’ 不能应用于’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) ));