Как создать запрос LINQ из текста во время выполнения?
У меня есть
class A {
public int X;
public double Y;
public string Z;
// and more fields/properties ...
};
и List<A> data
, и может построить запрос linq, например,
var q = from a in data where a.X > 20 select new {a.Y, a.Z};
Затем dataGridView1.DataSource = q.ToList();
отображает выбор в моем DataGridView.
Теперь вопрос, можно ли построить запрос из текста, введенного пользователем во время выполнения? Как
var q = QueryFromText("from a in data where a.X > 20 select new {a.Y, a.Z}");
Дело в том, что пользователь (обладающий навыками программирования) может динамически и свободно выбирать отображаемые данные.
Ответы
Ответ 1
Ну, вы можете использовать CSharpCodeProvider
для компиляции кода во время выполнения. Посмотрите на Snippy для примера этого. В этом случае вам нужно скомпилировать код пользователя в методе, который принимает List<A>
, называемый data
. Мой опыт в том, что он работает, но он может быть немного затруднительным, чтобы получить право - особенно с точки зрения добавления соответствующих ссылок и т.д.
Ответ 2
Динамический Linq baby!
r.e. комментарий.
Да, пример, написанный, может быть невозможен с помощью Dynamic Linq, но если вы отформоруете константы, например. 'from a data' вы остаетесь с 'where' и 'select', которые могут быть выражены динамическим linq.
поэтому два текстовых поля, возможно, три, если вы включите orderby, могут удовлетворить ваши требования.
Просто мысль.
У Джона есть интересный подход, но я бы не поддавался компиляции и выполнению безудержного кода.
Ответ 3
Отвечая на него довольно поздно; хотя, это поможет кому-то, кто посещает эту страницу.
У меня было подобное требование, и я решил его путем динамической компиляции строки в качестве запроса LINQ
, выполняя ее по сборке в памяти и собирая результат. Только catch - это вход пользователя, который должен быть действительным С# компилируемым кодом, иначе он возвращает сообщение исключения вместо результата.
Код довольно длинный, поэтому вот ссылка github
Пример приложения на github показывает несколько примеров, включая проекцию.
Ответ 4
Хотя могут быть некоторые способы сделать это, LINQ просто не предназначен для этого сценария. Использование CodeDOM (как предположил Джон), вероятно, является единственным способом сделать это легко. Если вы доверяете пользователю и у него есть навыки программирования, возможно, вы просто можете использовать старомодные методы и позволить пользователю вводить запрос с помощью SQL?
Если вы, с другой стороны, хотите создать визуальный инструмент для построения запросов, вам не нужно создавать их, составляя строки, и вместо этого вы можете создавать деревья выражений. Например, используя Linq Kit и AsExpandable
.
Ответ 5
проверить эту библиотеку
http://msdn.microsoft.com/en-us/vcsharp/bb894665.aspx