Разбирайте строку в запрос LINQ
Какой метод будет считаться наилучшей практикой для разбора строки LINQ в запросе?
Или, другими словами, какой подход имеет смысл конвертировать:
string query = @"from element in source
where element.Property = ""param""
select element";
в
IEnumerable<Element> = from element in source
where element.Property = "param"
select element;
предполагая, что source
относится к IEnumerable<Element>
или IQueryable<Element>
в локальной области.
Ответы
Ответ 1
Для этого требуется синтаксический анализ текста и интенсивное использование System.Linq.Expressions. Я сделал несколько игр с этим здесь и здесь. Код во второй статье несколько обновляется от первого, но все еще грубого в пятнах. Я продолжал обходить это случаем и иметь несколько более чистую версию, которую я хотел бы опубликовать, если у вас есть интерес. У меня это довольно близко к поддержке хорошего подмножества ANSI SQL 89.
Ответ 2
Это может сработать для вас: эквивалент С# эквивалент?
Ответ 3
Вам понадобится парсер языка С# (по крайней мере, v3.5, возможно, v4.0, в зависимости от того, какие функции языка С# вы хотите поддерживать в LINQ). Вы получите результаты анализатора и подаете его непосредственно в дерево выражений с использованием шаблона посетителя. Я еще не уверен, но я готов поспорить, вам также понадобится какой-то анализ типа, чтобы полностью генерировать узлы Expression.
Я ищу то же, что и вы, но мне это действительно не так плохо, поэтому я не искал и не писал ни одного кода в этих строках.
Я написал что-то, что берет ввод строки пользователя и компилирует его в динамическую сборку, используя класс поставщика Microsoft.CSharp.CSharpCodeProvider
. Если вы просто хотите взять строки кода и выполнить результат, это должно вам подойдет.
Вот описание консольного инструмента, который я написал, LinqFilter:
http://bittwiddlers.org/?p=141
Здесь находится исходный репозиторий. LinqFilter/Program.cs демонстрирует, как использовать компилятор для компиляции выражения LINQ:
http://bittwiddlers.org/viewsvn/trunk/public/LinqFilter/?root=WellDunne
Ответ 4
Это может или не поможет вам, но зайдите в LINQ Dynamic Query Library.
Ответ 5
Начиная с .NET 4.6 вы можете использовать CSharpScript для синтаксического анализа Linq, предполагая, что выражение, которое вы хотите проанализировать, находится в запросе, это сделает следующее:
string query = "from element in source where element.Property = ""param"" select element";
IEnumerable result = null;
try
{
var scriptOptions = ScriptOptions.Default.WithReferences(typeof(System.Linq.Enumerable).Assembly).WithImports("System.Linq");
result = await CSharpScript.EvaluateAsync<IEnumerable>(
query,
scriptOptions,
globals: global);
} catch (CompilationErrorException ex) {
//
}
Не забудьте передать свой (Data) источник, с которым хотите работать, с глобальными переменными, чтобы иметь доступ к ним из script.
Ответ 6
В то время как это не дает конкретного примера для ответа на ваш вопрос, я бы подумал, что лучше всего было бы построить дерево выражений из строки.
В этом вопросе я спросил, как фильтровать запрос linq с помощью строки, которая показывает, что вы создаете часть дерева выражений. Однако эта концепция может быть расширена для построения целого дерева выражений, представляющего вашу строку.
См. статью из Microsoft.
Есть, вероятно, и другие хорошие сообщения. Кроме того, я думаю, что что-то вроде RavenDB делает это уже в своей базе кода для определения индексов.