2009-03-24 40 views
60

Soy nuevo en LINQ y quiero saber cómo ejecutar la cláusula where múltiple. Esto es lo que quiero lograr: devolver registros filtrando ciertos nombres de usuario. Probé el código siguiente pero no funcionó como esperaba.Múltiple cláusula WHERE en Linq

DataTable tempData = (DataTable)grdUsageRecords.DataSource; 
var query = from r in tempData.AsEnumerable() 
      where ((r.Field<string>("UserName") != "XXXX") || (r.Field<string>("UserName") != "XXXX"))        
      select r;  

      DataTable newDT = query.CopyToDataTable(); 

Gracias por la ayuda con antecedencia !!!

Respuesta

98

Bueno, se puede simplemente poner múltiple "donde" cláusulas en forma directa, pero no creo que desee. Múltiple "donde" cláusulas termina con un filtro restrictivo más - Creo que quieres una restrictiva menos. Creo que realmente quiere:

DataTable tempData = (DataTable)grdUsageRecords.DataSource; 
var query = from r in tempData.AsEnumerable() 
      where r.Field<string>("UserName") != "XXXX" && 
        r.Field<string>("UserName") != "YYYY" 
      select r; 

DataTable newDT = query.CopyToDataTable(); 

Nota del & & en lugar de ||. Desea seleccionar la fila si el nombre de usuario no es XXXX y el nombre de usuario no es YYYY.

EDITAR: Si tiene toda una colección, es incluso más fácil. Supongamos que la colección se llama ignoredUserNames:

DataTable tempData = (DataTable)grdUsageRecords.DataSource; 
var query = from r in tempData.AsEnumerable() 
      where !ignoredUserNames.Contains(r.Field<string>("UserName")) 
      select r; 

DataTable newDT = query.CopyToDataTable(); 

Lo ideal sería que te gustaría hacer de esto una HashSet<string> para evitar la Contains la llamada que toma mucho tiempo, pero si la colección es lo suficientemente pequeño que no hará mucha probabilidades.

+0

tengo una colección UserName. ¿Cómo lo paso a la cláusula where de forma dinámica? – Ganesha

+1

Sé que esto fue respondida hace mucho tiempo, pero mi sugerencia rápida sería la de tratar y el uso se unen más que contiene. Es mucho más eficiente (especialmente si su conjunto de datos contiene un tamaño razonable). – ArtificialGold

17

@ Jon Jon, ¿estás diciendo el uso de varias cláusulas donde, por ejemplo,

var query = from r in tempData.AsEnumerable() 
      where r.Field<string>("UserName") != "XXXX" 
      where r.Field<string>("UserName") != "YYYY" 
      select r; 

es más que el uso de restictive

var query = from r in tempData.AsEnumerable() 
      where r.Field<string>("UserName") != "XXXX" && r.Field<string>("UserName") != "YYYY" 
      select r; 

creo que son equivalentes por lo que el resultado va.

Sin embargo, no he probado, si se utiliza múltiples, donde en el primer ejemplo en la causa 2 subconsultas, es decir .Where(r=>r.UserName!="XXXX").Where(r=>r.UserName!="YYYY) o el traductor LINQ es inteligente suficiente como para ejecutar .Where(r=>r.UserName!="XXXX" && r.UsernName!="YYYY")

6

Además, el método bool puede utilizar (s)

consulta:

DataTable tempData = (DataTable)grdUsageRecords.DataSource; 
var query = from r in tempData.AsEnumerable() 
      where isValid(Field<string>("UserName"))// && otherMethod() && otherMethod2()       
      select r; 

     DataTable newDT = query.CopyToDataTable(); 

Método:

bool isValid(string userName) 
{ 
    if(userName == "XXXX" || userName == "YYYY") 
     return false; 
    else return true; 
} 
28

@Theo

El traductor LINQ es lo suficientemente inteligente como para ejecutar:

.Where(r => r.UserName !="XXXX" && r.UsernName !="YYYY") 

He prueba de esto en LINQPad ==> SÍ, LINQ traductor es lo suficientemente inteligente :))

Cuestiones relacionadas