无法在通用表达式构建器中应用不区分大小写

时间:2017-03-17 04:48:17

标签: c# entity-framework linq generics

我有一个通用表达式构建器,其代码如下:

 public class EntityExpression
{
    public enum Op
    {
        Equals,
        GreaterThan,
        LessThan,
        GreaterThanOrEqual,
        LessThanOrEqual,
        Contains,
        StartsWith,
        EndsWith,
        Nothing,
            StringEquals
    }
    public class Filter
    {
        public string PropertyName { get; set; }
        public Op Operation { get; set; }
        public object Value { get; set; }

        public static Op Operatorstranslation(string InputOperator)
        {
            switch (InputOperator)
            {
                case "eq":
                    return Op.Equals;
                case "startswith":
                    return Op.StartsWith;
                case "contains":
                    return Op.Contains;
            }
            return Op.Nothing;

        }

    }
    public static class ExpressionBuilder
    {
        private static MethodInfo containsMethod = typeof(string).GetMethod("Contains" );
        private static MethodInfo startsWithMethod = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });
        private static MethodInfo endsWithMethod = typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) });
        private static MethodInfo compareMethod = typeof(string).GetMethod("Compare", new Type[] { typeof(string), typeof(string), typeof(StringComparison) });

        public static Expression<Func<T, bool>> GetExpression<T>(IList<Filter> filters)
        {
            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
                        exp = Expression.AndAlso(exp, GetExpression<T>(param, filters[0], filters[1]));

                    filters.Remove(f1);
                    filters.Remove(f2);

                    if (filters.Count == 1)
                    {
                        exp = Expression.AndAlso(exp, GetExpression<T>(param, filters[0]));
                        filters.RemoveAt(0);
                    }
                }
            }

            return Expression.Lambda<Func<T, bool>>(exp, param);
        }

        private static Expression GetExpression<T>(ParameterExpression param, Filter filter)
        {
            MemberExpression member = Expression.Property(param, filter.PropertyName);
          //  ConstantExpression valueExpression = Expression.Constant(filter.Value);


            var propertyType = ((PropertyInfo)member.Member).PropertyType;
            var converter = TypeDescriptor.GetConverter(propertyType);

            if (!converter.CanConvertFrom(typeof(string))) // 2
                throw new NotSupportedException();


            var propertyValue = converter.ConvertFromInvariantString(filter.Value.ToString());
            var constant = Expression.Constant(propertyValue);
            var valueExpression = Expression.Convert(constant, propertyType);


            ConstantExpression stringComparisonConstant = Expression.Constant(StringComparison.OrdinalIgnoreCase);



            switch (filter.Operation)
            {
                case Op.Equals:
                    return Expression.Equal(member, valueExpression);

                case Op.GreaterThan:
                    return Expression.GreaterThan(member, valueExpression);

                case Op.GreaterThanOrEqual:
                    return Expression.GreaterThanOrEqual(member, valueExpression);

                case Op.LessThan:
                    return Expression.LessThan(member, valueExpression);

                case Op.LessThanOrEqual:
                    return Expression.LessThanOrEqual(member, valueExpression);



                      case Op.Contains:

                    return Expression.Call(member, containsMethod, valueExpression);


                case Op.StringEquals:
                    var zeroConstant = Expression.Constant(0);
                    var compareExpression = Expression.Call(compareMethod, member, valueExpression, stringComparisonConstant);
                    return Expression.Equal(compareExpression, zeroConstant);



                case Op.StartsWith:
                            return Expression.Call(member, startsWithMethod, valueExpression);

                        case Op.EndsWith:
                            return Expression.Call(member, endsWithMethod, valueExpression);


            }

            return null;
        }

        private static BinaryExpression GetExpression<T>
        (ParameterExpression param, Filter filter1, Filter filter2)
        {
            Expression bin1 = GetExpression<T>(param, filter1);
            Expression bin2 = GetExpression<T>(param, filter2);

            return Expression.AndAlso(bin1, bin2);
        }
    }


}

我的问题是这段代码不适用于不区分大小写的情况,尤其是containsMethod,显然是因为该操作中没有空闲代码,但是compareMethod可以完全适用于任何情况,因为正确的代码用于不敏感。

我希望我的containsMethod适用于任何情况(上方或下方)。任何人都可以帮我这个代码吗?

0 个答案:

没有答案