2011-04-15 11 views
10

Tengo un escenario donde tengo que usar una condición dynamic where en LINQ.Dinámico donde condición en LINQ

Quiero algo como esto:

public void test(bool flag) 
{ 
    from e in employee 
    where e.Field<string>("EmployeeName") == "Jhom" 
    If (flag == true) 
    { 
     e.Field<string>("EmployeeDepartment") == "IT" 
    } 
    select e.Field<string>("EmployeeID") 
} 

Yo sé que no podemos usar el 'Si' en el medio de la consulta LINQ, pero ¿cuál es la solución para esto?

Por favor, ayuda ...

+0

No es realmente * dynamic *, todo lo que necesita hacer es llamar explícitamente a los métodos LINQ y encadenarlos en función de una condición. –

Respuesta

9

lo tanto, si flag es false es necesario que todo Jhoms, y si flag es cierto que sólo necesitan las Jhoms en el departamento de TI

Esta condición

!flag || (e.Field<string>("EmployeeDepartment") == "IT" 

satisface ese criterio (siempre es cierto si el indicador es falso, etc ..), por lo que la consulta se convertirá en:

from e in employee  
where e.Field<string>("EmployeeName") == "Jhom" 
    && (!flag || (e.Field<string>("EmployeeDepartment") == "IT") 
select e.Field<string>("EmployeeID") 

También, este e.Field<string>("EmployeeID") negocio, huele a softcoding, podría echar un vistazo a eso. Supongo que

from e in employee  
where e.EmployeeName == "Jhom" 
    && (!flag || (e.EmployeeDepartment == "IT") 
select e.EmployeeID 

sería más compacto y menos propenso a errores de tipeo.


EDITAR: Esta respuesta funciona para este caso particular. Si tiene muchas de estas consultas, investigue los patrones propuestos en las otras respuestas.

+0

Este es el más directo. –

10

Por favor revise el post completo en el blog: Dynamic query with Linq

Hay dos opciones que se pueden utilizar:

Dynamic LINQ library

string condition = string.Empty; 
if (!string.IsNullOrEmpty(txtName.Text)) 
    condition = string.Format("Name.StartsWith(\"{0}\")", txtName.Text); 

EmployeeDataContext edb = new EmployeeDataContext(); 
if(condition != string.empty) 
{ 
    var emp = edb.Employees.Where(condition); 
///do the task you wnat 
} 
else 
{ 
//do the task you want 
} 

Predicate Builder

Predica Te constructor funciona de forma similar a la biblioteca dinámica LINQ pero es un tipo seguro:

var predicate = PredicateBuilder.True<Employee>(); 

if(!string.IsNullOrEmpty(txtAddress.Text)) 
    predicate = predicate.And(e1 => e1.Address.Contains(txtAddress.Text)); 

EmployeeDataContext edb= new EmployeeDataContext(); 
var emp = edb.Employees.Where(predicate); 

diferencia entre la biblioteca de arriba:

  • PredicateBuilder permite construir consultas dinámicas typesafe.
  • La biblioteca Dynamic LINQ permite generar consultas con cláusulas Where y OrderBy dinámicas especificadas mediante las cadenas.
+0

El primer ejemplo parece retirarse del contexto. ¿Cuál es el punto de verificar 'condición 'de vacío si se acaba de asignar' string.Empty'? Voy a corregir esto ahora .. –

+0

@gaearon - si hay más no de la condición que está yi puesto allí ... Ya publicado el enlace de la publicación completa donde se puede ver el detalle –

+0

@gaearon - la respuesta se actualiza ahora ... ...... con si condición –

2

Puede métodos de la cadena:

public void test(bool flag) 
{ 
    var res = employee.Where(x => x.EmployeeName = "Jhom"); 

    if (flag) 
    { 
     res = res.Where(x => x.EmployeeDepartment == "IT") 
    } 

    var id = res.Select(x => x.EmployeeID); 
} 
+0

No entiendo por qué el voto a favor? ¿Tal vez una explicación podría ayudarme a mejorar mi respuesta? – mathieu

+0

Creo que esto no es lo que se pide. El problema no es un nombre de propiedad desconocido, sino desconocido (puedo llamarlo así) 'chainity'. Su respuesta no refleja exactamente cómo puede encadenar consultas con Dynamic LINQ. Además, su ejemplo es incorrecto porque 'EmployeeName' no es propiedad de 'Employee', es una cadena que se pasa al método' Field'. –

+0

Y, por último, pero probablemente la razón principal para downvote, es mi opinión subjetiva de que esta es una mala idea. La pregunta ** no requiere Dynamic LINQ **, todo lo que se necesita es el encadenamiento arbitrario, que ya es posible utilizando llamadas explícitas al método LINQ. El código dinámico y no seguro solo debe introducirse donde sea difícil lograr lo mismo con la seguridad del tipo (por ejemplo, el usuario ingresa una expresión complicada directamente en el cuadro de búsqueda). ** Dynamic LINQ es mejor que el análisis, pero mucho peor que la consulta de tipo seguro, que es muy posible e incluso deseable con esta pregunta. ** –

0
from e in employee  
where e.Field<string>("EmployeeName") == "Jhom" && 
(!flag || e.Field<string>("EmployeeDepartment") == "IT") 
select e.Field<string>("EmployeeID") 
0

Puede llamar métodos LINQ explícitamente y encadenarlos condicionalmente.

public IEnumerable<string> FilterEmployees (IEnumerable<Employee> source, bool restrictDepartment) 
{ 
    var query = source.Where (e => e.Field<string>("EmployeeName") == "Jhom"); 

    if (restrictDepartment) // btw, there's no need for "== true" 
     query = query.Where (e => e.Field<string>("EmployeeDepartment") == "IT"); 

    return query.Select (e => e.Field<string>("EmployeeID")); 
}