Преобразование строки фильтра в делегат C # - PullRequest
1 голос
/ 17 марта 2011

У меня есть набор классов, которые я использую для уровня доступа к данным для некоторых клиентов.В рамках доступа к данным я разрешаю отправку набора фильтров в следующем формате:

"{Member[.Member....]}{Operator}{Value}"

Я хотел бы превратить эти строки в делегаты для использования в запросе LINQ, например:

.Where([delegate returned by a factory])

Вот более конкретный пример: выражение

IEnumerable<Parent> parents = GetSomeParents();
string filter = "Child.Id=5";
var expression = FilterFactory<Parent>.GetExpression(filter);

parents = parents.Where(expression);

будет содержать делегат: parent => parent.Child.Id == 5

Есть ли способ с помощью отражения создать конструкцию FilterFactory в общемспособ обработать любой путь члена я отправляю?Пути с индексацией не требуются, но было бы неплохо.

1 Ответ

4 голосов
/ 17 марта 2011

Да, абсолютно! Это тоже очень весело.

Один из способов сделать это - использовать динамическую библиотеку запросов LINQ и получить там компилятор выражений, который у них есть. У меня тоже есть что-то очень похожее в моем проекте MetaSharp .

Но вы также можете сделать это самостоятельно, если синтаксис или функции не совсем соответствуют тому, что вы хотите. Общая идея заключается в том, что вам нужно проанализировать строку и создать дерево выражений, которое представляет то, что вы анализируете. В .NET объекты дерева выражений можно найти в System.Linq.Expressions. Если у вас есть дерево, вы можете вызвать Compile (), и оно будет динамически скомпилировано в делегат. Попробуйте прочитать о шаблонах конечного автомата и посетителя, чтобы выяснить, как лучше всего проанализировать произвольное выражение, подобное приведенному выше.

PS Я бы не рекомендовал использовать регулярные выражения!

...