IQueryable <> динамическое упорядочение / фильтрация с GetValue завершается неудачно

2

Я пытаюсь отфильтровать результаты из базы данных с помощью Entity Framework CTP5. Вот мой текущий метод.

IQueryable<Form> Forms = DataContext.CreateFormContext().Forms;
foreach(string header in Headers) {
    Forms = Forms.Where(f => f.GetType()
                              .GetProperty(header)
                              .GetValue(f, null)
                              .ToString()
                              .IndexOf(filter,
                                  StringComparison.InvariantCultureIgnoreCase) >= 0);
}

Однако я обнаружил, что GetValue не работает с использованием Entity Framework. Это происходит, когда тип if IEnumerable<>, но не IQueryable<>

Есть ли альтернатива, которую я могу использовать для получения того же эффекта?

  • 1
    Разница между IEnumerable и IQueryable заключается в том, что Linq для объектов (IEnumerable) принимает делегатов в качестве параметров и выполняет код напрямую, поэтому все, что компилируется, возможно. EF использует IQueryable, и его синтаксический анализатор выражений имеет ограничения на то, что он может распознавать и анализировать.
Теги:
entity-framework

1 ответ

3
Лучший ответ
public static IQueryable<T> Like<T>(this IQueryable<T> source, string propertyName, string keyword) {
    Type type = typeof(T);
    ParameterExpression parameter = Expression.Parameter(type, "param");
    MemberExpression memberAccess = Expression.MakeMemberAccess(parameter, type.GetProperty(propertyName));

    ConstantExpression constant = Expression.Constant("%" + keyword + "%");
    MethodInfo contains = memberAccess.Type.GetMethod("Contains");

    MethodCallExpression methodExp = Expression.Call(memberAccess, contains, Expression.Constant(keyword));
    Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(methodExp, parameter);
    return source.Where(lambda);
}

Вы бы назвали это так

Forms = Forms.Like(header, filter);

Я не проводил проверки переданных параметров. Например, вы должны проверить, существует ли метод Contains для типа свойства, с которым вы проверяете. Поэтому он не будет работать на int или что-то в этом роде.

  • 0
    Это выглядит многообещающе ... Я сделаю это

Ещё вопросы

Сообщество Overcoder
Наверх
Меню