2010-04-18 13 views
10

Tengo un¿Cómo construir una consulta LINQ a partir del texto en tiempo de ejecución?

class A { 
    public int X; 
    public double Y; 
    public string Z; 
    // and more fields/properties ... 
}; 

y una List<A> data y puede construir una consulta LINQ, como por ejemplo,

var q = from a in data where a.X > 20 select new {a.Y, a.Z}; 

Entonces dataGridView1.DataSource = q.ToList(); la posibilidad de selección en mi DataGridView.

Ahora la pregunta, ¿es posible crear la consulta a partir de un texto que el usuario ha ingresado en tiempo de ejecución? Como

var q = QueryFromText("from a in data where a.X > 20 select new {a.Y, a.Z}"); 

El punto es que el usuario (que tiene conocimientos de programación) puede seleccionar de forma dinámica y libre los datos mostrados.

Respuesta

4

Bueno, puede usar CSharpCodeProvider para compilar el código en tiempo de ejecución. Eche un vistazo a Snippy para ver un ejemplo de esto. En este caso, deberá compilar el código de usuario en un método que acepte List<A> llamado data. Mi experiencia es que funciona, pero puede ser un poco difícil de conseguir, especialmente en términos de agregar las referencias adecuadas, etc.

+3

+1 pero me preocuparía compilar y ejecutando código arbitrario. requeriría la debida diligencia, y habiendo hecho tal cosa, digo que no es divertido y perseguirá sus sueños. ;-) –

5

Dynamic Linq baby!

r.e. comentario.

Sí, el ejemplo tal como está escrito puede no ser posible utilizando Dynamic Linq, pero si factoriza las constantes, p. 'de a in data' te queda un 'where' y un 'select' que se pueden expresar con dynamic linq.

por lo que dos cuadros de texto, tal vez tres si incluye un pedido, podrían satisfacer sus requisitos.

Solo un pensamiento.

Jon tiene un enfoque interesante, pero me preocuparía la compilación y la ejecución de código sin restricciones.

+0

No veo cómo esto es posible con Dynamic Linq. – Danvil

+0

@Danvil: tienes razón, tu ejemplo tal como está escrito puede no ser posible, pero cuando factorizas las constantes como ... ah diablos, simplemente editaré la respuesta ... –

0

Aunque puede haber algunas formas de hacerlo, LINQ simplemente no está diseñado para este escenario . Usar CodeDOM (como sugirió Jon) es probablemente la única forma de hacerlo fácilmente. Si confías en el usuario y él/ella tiene habilidades de programación, quizás podrías simplemente usar métodos pasados ​​de moda y dejar que el usuario ingrese la consulta usando SQL.

Si, por otro lado, elige crear alguna herramienta visual para construir consultas, no necesita construirlas componiendo cadenas y puede componer árboles de expresiones en su lugar. Por ejemplo, usando Linq Kit y AsExpandable.

+0

Tengo los datos en forma de una clase y no en una base de datos. Pensé que al usar LINQ, quizás podría lograr un comportamiento similar interactivo en las clases, como las consultas SQL en una base de datos. – Danvil

1

contestarla bastante tarde; sin embargo, ayudará a alguien que visite esta página.

Tuve un requisito similar y lo resolví compilando dinámicamente cadena como consulta LINQ, ejecutándola sobre la recopilación en memoria y recopilando el resultado. La única captura es que la entrada del usuario debe ser un código compilable válido de C#, de lo contrario, devuelve un mensaje de excepción en lugar de un resultado.

Código es bastante largo, así que aquí es la aplicación de ejemplo github link

en github muestra varios ejemplos que incluyen proyección.

Cuestiones relacionadas