2010-03-13 8 views
7

Estaba leyendo una pregunta reciente en using conditionals in Linq y me recordó un problema que no he podido resolver. Al construir Linq para consultas SQL de forma programática, ¿cómo se puede hacer esto cuando no se conoce el número de condicionales hasta el tiempo de ejecución? Por ejemplo, en el código siguiente, la primera cláusula crea un IQueryable que, si se ejecutara, seleccionaría todas las tareas (llamadas problemas) en la base de datos, la segunda cláusula refinará eso solo para los problemas asignados a un departamento si uno tiene ha sido seleccionado en un cuadro combinado (que tiene su elemento seleccionado vinculado a la propiedad departmentToShow).Usar condicionales en Linq Programativamente

¿Cómo podría hacer esto usando la colección selectedItems en su lugar?

IQueryable<Issue> issuesQuery; 

// Will select all tasks 
issuesQuery = from i in db.Issues 
       orderby i.IssDueDate, i.IssUrgency 
       select i; 

// Filters out all other Departments if one is selected 
    if (departmentToShow != "All") 
    { 
     issuesQuery = from i in issuesQuery 
         where i.IssDepartment == departmentToShow 
         select i; 
    } 

Por cierto, el código anterior se simplifica, en el código actual hay alrededor de una docena de cláusulas que refinan la consulta en base a los usuarios buscar y configuración del filtro.

Respuesta

7

Si el número de condiciones no se conoce, entonces es más fácil de usar sintaxis lambda en lugar de comprensión de consulta, es decir:

IQueryable<Issue> issues = db.Issues; 
if (departmentToShow != "All") 
{ 
    issues = issues.Where(i => i.IssDepartment == departmentToShow); 
} 
issues = issues.OrderBy(i => i.IssDueDate).ThenBy(i => i.IssUrgency); 

(Suponiendo que desea que el pedido que suceda después de la filtración, que debería ser el caso - No estoy seguro de si Linq generará una consulta optimizada si intenta hacer el pedido primero).

Si usted tiene un gran número de condiciones opcionales continuación, se puede limpiar con predicados:

List<Predicate<Issue>> conditions = new List<Predicate<Issue>>(); 
if (departmentToShow != "All") 
    conditions.Add(i => i.IssDepartment == departmentToShow); 
if (someOtherThing) 
    conditions.Add(anotherPredicate); 
// etc. snip adding conditions 

var issues = from i in issues 
      where conditions.All(c => c(i)) 
      orderby i.IssDueDate, i.IssUrgency; 

o simplemente utilizar PredicateBuilder que es probablemente más fácil.

+0

En realidad, un elemento de mi lista de tareas pendientes es sacar el pedido explícito y agregarlo a la interfaz para que el usuario tenga cierto control. –

+0

En la expresión anterior de Lambda, ¿cómo funcionaría eso con departmentToShow como una colección de un cuadro combinado, pensé que lo que tienes es exactamente lo mismo que la consulta que tengo. Debo confesar que soy un principiante y Lambdas es una de esas cosas que tienen más sentido para mí en los libros que en la práctica. –

+0

@Mike B: es similar a lo que tienes, pero obviamente menos detallado y tu versión original hace un pedido antes del segundo filtro (quieres que ocurra al final). Si 'departmentToShow' es una colección, entonces usted escribe' departmentToShow.Contains (i.IssDepartment) 'en lugar de' i.IssDepartment == departmentToShow'. – Aaronaught

Cuestiones relacionadas