我有一个复杂的搜索功能,允许用户从字段列表中进行选择,然后选择搜索值和修改器。例如,如果这是购物车,则用户正在搜索产品并可以搜索匹配的产品:
名称包含" ball" 价格低于" 5.00" 运出"美国"
等。
我的问题是,我有25个不同的字段要搜索,有些是与子孙对象有关的复杂字体。因此,对于每个字段,我都有一个if结构,如:
if (mod == "!=")
{
allInvestigators = allInvestigators.Where(i => !i.Indicators.Any(j => j.Title.ToLower().Contains(txtVal)));
}
else if (mod == "==")
{
allInvestigators = allInvestigators.Where(i => i.Indicators.Any(j => j.Title.ToLower() == txtVal));
}
else
{
allInvestigators = allInvestigators.Where(i => i.Indicators.Any(j => j.Title.ToLower().Contains(txtVal)));
}
所以为了说清楚,用户可以选择一个字段,一个搜索修饰符(==,<,>,!=),并且可以在一次搜索中使用其中的几个过滤器!有没有人对如何缩小此代码有任何想法?
更新这就是我现在的位置..
allInvestigators = allInvestigators.Where(i =>
(i.Address.State.ToLower().Contains(txtVal) && mod == "=") ||
(i.Address.State.ToLower() == txtVal && mod == "==") ||
(i.Address.State.ToLower() != txtVal && mod == "!=")
);
答案 0 :(得分:2)
您可以尝试将字段查询放入变量列表中,并且可以循环使用它们并正确应用它们。不是完整的代码,只是为了灵感:
Expression<Func<Item, Boolean>> expr = j => j.Title.ToLower().Contains(txtVal);
allInvestigators = allInvestigators.Where(i => !i.Indicators.AsQueryable().Any(expr));
答案 1 :(得分:1)
查看“Nutshell中的C#4.0 / 5.0”中描述的PredicateBuilder
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T> () { return f => true; }
public static Expression<Func<T, bool>> False<T> () { return f => false; }
public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
}
}
它可以用于首先构建Expression / Specification。
您可以在博文Specifications Pattern with LINQ中找到与AndSpecification
想法类似的OrSpecification
,NotSpecification
,PredicateBuilder
的示例。
答案 2 :(得分:0)
您可以使用String.Equals
allInvestigators = allInvestigators.Where(i =>
(i.Address.State.ToLower().Contains(txtVal) && mod == "=") ||
(i.Address.State.Equals(txtVal, StringComparison.CurrentCultureIgnoreCase) && mod == "==") ||
(!i.Address.State.Equals(txtVal, StringComparison.CurrentCultureIgnoreCase) && mod == "!=")
);