我正在使用ExpressionBuilder构建表达式来搜索ObservableCollection中的项目,但该表达式从集合中敏感地搜索。我想使它不区分大小写。我怎么做到的? 我的代码在这里:
public class ExpressionBuilder
{
private MethodInfo containsMethod = typeof(string).GetMethod("Contains");
private MethodInfo startsWithMethod = typeof(string).GetMethod("StartsWith",new Type[] { typeof(string)});
private MethodInfo endsWithMethod = typeof(string).GetMethod("EndsWith",new Type[] { typeof(string)});
public Expression<Func<T, bool>> GetExpression<T>(IList<SearchFilter> filter)
{
var filters = new List<SearchFilter>(filter);
if (filters.Count == 0)
return null;
ParameterExpression param = Expression.Parameter(typeof(T), "t");
Expression exp = null;
if (filters.Count == 1)
exp = GetExpression<T>(param, filters[0]);
else if (filters.Count == 2)
exp = GetExpression<T>(param, filters[0], filters[1]);
else
{
while (filters.Count > 0)
{
var f1 = filters[0];
var f2 = filters[1];
if (exp == null)
exp = GetExpression<T>(param, filters[0], filters[1]);
else
if(filter[1].Andor == "And" || filter[1].Andor == null)
{
exp = Expression.AndAlso(exp, GetExpression<T>(param, filters[0], filters[1]));
}
else
{
exp = Expression.Or(exp, GetExpression<T>(param, filters[0], filters[1]));
}
filters.Remove(f1);
filters.Remove(f2);
if (filters.Count == 1)
{
if (filter[1].Andor == "And" || filter[1].Andor == null)
{
exp = Expression.AndAlso(exp, GetExpression<T>(param, filters[0]));
}
else
{
exp = Expression.Or(exp, GetExpression<T>(param, filters[0]));
}
filters.RemoveAt(0);
}
}
}
return Expression.Lambda<Func<T, bool>>(exp, param);
}
private Expression GetExpression<T>(ParameterExpression param, SearchFilter filter)
{
object con;
MemberExpression member = Expression.Property(param, filter.PropertyName);
if (filter.PropertyName == "Emp_ID")
{
con = Convert.ChangeType(filter.Value,Convert.ToInt32(filter.Value).GetType());
}
else
{
con = Convert.ChangeType(filter.Value.ToString().ToLower(),filter.Value.GetType());
}
ConstantExpression constant = Expression.Constant(con);
Expression expReturn = null;
switch (filter.Operation)
{
case Operation.Equals:
expReturn = Expression.Equal(member,Expression.Convert(constant, member.Type));
break;
case Operation.GreaterThan:
expReturn = Expression.GreaterThan(member,Expression.Convert(constant, member.Type));
break;
case Operation.GreaterThanOrEqual:
expReturn = Expression.GreaterThanOrEqual(member,Expression.Convert(constant, member.Type));
break;
case Operation.LessThan:
expReturn = Expression.LessThan(member,Expression.Convert(constant, member.Type));
break;
case Operation.LessThanOrEqual:
expReturn = Expression.LessThanOrEqual(member,Expression.Convert(constant, member.Type));
break;
case Operation.Contains:
expReturn = Expression.Call(member, containsMethod,Expression.Convert(constant,member.Type));
break;
case Operation.StartsWith:
expReturn = Expression.Call(member, startsWithMethod,Expression.Convert(constant, member.Type));
break;
case Operation.EndsWith:
expReturn = Expression.Call(member, endsWithMethod,Expression.Convert(constant, member.Type));
break;
}
return expReturn;
}
private BinaryExpression GetExpression<T>(ParameterExpression param, SearchFilter filter1, SearchFilter filter2)
{
Expression bin1 = GetExpression<T>(param, filter1);
Expression bin2 = GetExpression<T>(param, filter2);
if(filter2.Andor == "And" || filter2.Andor == null)
{
return Expression.AndAlso(bin1, bin2);
}
return Expression.Or(bin1, bin2);
}
上面的类构建表达式。
这就是我如何使用该表达式从ObservableCollection中搜索:
ExpressionBuilder ex = new ExpressionBuilder();
var exp = ex.GetExpression<Employee>(SearchFilters);
employees = new ObservableCollection<Employee>(EMP.AsQueryable().Where(exp).ToList());