如何构建从ObservableCollection不敏感地搜索项目的表达式

时间:2016-03-08 05:25:09

标签: c# expressionbuilder

我正在使用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());

0 个答案:

没有答案