как создать строгий типизированный запрос LINQ без учета регистра в C #?

Я пытаюсь создать метод расширения для IQuerable следующим образом:

public static IQueryable<T> FilterByString<T>(this IQueryable<T> query, 
  Expression<Func<T, string>> propertySelector, 
  StringOperator operand, 
  string value)

, который обобщит что-то вроде этого:

query.Where(o => o.Name.ToLower().StartsWith(filterObject.Name.ToLower()))

в:

q.FilterByString(o => o.Name, filterObject.NameOperator, filterObject.Name)

, чтобы разрешить установку оператора фильтрации (т.е. EndsWith, Contains).

Я видел в Google некоторые решения для фильтрации с учетом регистра, которые требуют использования имени свойства в виде строки вместо строгого типа propertySelectorExpression. Я также видел решение для нечувствительной реализации Contains () с использованием IndexOf () но ни один из них, похоже, не соответствует моим потребностям.

На данный момент у меня есть это, но он не работает (кроме вызова "ToLower ()"):

static MethodInfo miTL = typeof(String).GetMethod("ToLower", System.Type.EmptyTypes);
static MethodInfo miS = typeof(String).GetMethod("StartsWith", new Type[] { typeof(String) });
static MethodInfo miC = typeof(String).GetMethod("Contains", new Type[] { typeof(String) });
static MethodInfo miE = typeof(String).GetMethod("EndsWith", new Type[] { typeof(String) });

public static IQueryable<T> FilterByString<T>(this IQueryable<T> query, 
  Expression<Func<T, string>> propertySelector, 
  StringOperator operand, 
  string value)
{
    Expression constExp = Expression.Constant(value.ToLower());

    Expression dynamicExpression = null;

    switch (operand)
    {
        case StringOperator.StartsWith:
            dynamicExpression = Expression.Call(propertySelector, miTL);
            dynamicExpression = Expression.Call(dynamicExpression, miS, constExp);
            break;
        case StringOperator.Contains:
            dynamicExpression = Expression.Call(propertySelector, miTL);
            dynamicExpression = Expression.Call(dynamicExpression, miC, constExp);
            break;
        case StringOperator.EndsWith:
            dynamicExpression = Expression.Call(dynamicExpression, miTL);
            dynamicExpression = Expression.Call(dynamicExpression, miE, constExp);
            break;
        default:
            break;
    }

    LambdaExpression pred = Expression.Lambda(dynamicExpression);

    return (IQueryable<T>)query.Provider.CreateQuery(Expression.Call(typeof(Queryable), 
        "Where", new Type[] {query.ElementType}, query.Expression, pred));
}

Есть идеи?

5
задан wlf84k 13 October 2011 в 12:21
поделиться