Я пытаюсь создать метод расширения для 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));
}
Есть идеи?