Как создать запрос 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.