Построение динамических запросов и выражений linq

Обновлено: 05.07.2024

Linq to Entity позволяет очень выразительно со статической проверкой типов писать сложные запросы. Но иногда надо нужно сделать запросы чуть динамичнее. Например, добавить сортировку, когда имя колонки задано строкой.
Т.е. написать что то вроде:

На помощь в этом случае придет динамическое построение деревьев выражений (expression trees). Правда одних выражений будет недостаточно, потребуется динамически находить и конструировать шаблонные методы. Но и это не так сложно. Подробности ниже.

Сортировка запросов linq to entity, когда имя поля задано строкой

Вообще для упорядочивания данных, возвращаемых Linq — запросом, применяются 4 метода:

Напишем обобщенный метод, который будет принимать 3 аргумента.

Где source — исходный IQueriable, к которому нужно добавить упорядочивание; property – имя свойства, по которому производится сортировка; methodName – название метода упорядочивания из списка выше. Конечно, в боевом коде ApplyOrder сделан приватным, и пользователь имеет дело с методами:

Которые устроены тривиально и в итоге вызывают ApplyOrder.

Комментарии поясняют что происходит. Сначала делается дерево выражений, в котором происходит обращение к сортируемому полю. Затем из дерева выражений создается лямбда. Далее конструируется метод сортировки, способный принять лямбду. И, в конце концов, этот метод динамически запускается на выполнение.
Самым сложным моментом здесь оказывается динамическое создание шаблонного метода, что вынесено в отдельный метод расширения GetGenericMethod.

Показаный подход с минимальными измнениями можно адаптировать к IEnumerable<> для работы с Linq to objects.

Читайте также: