76 votes

Clause WHERE multiple dans Linq

Je suis nouveau sur LINQ et je veux savoir comment exécuter plusieurs clauses where. C’est ce que je veux réaliser: renvoyer des enregistrements en filtrant certains noms d’utilisateur. J'ai essayé le code ci-dessous mais je n'ai pas fonctionné comme prévu.

 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();
 

Merci pour l'aide à l'avance !!!

118voto

Jon Skeet Points 692016

Eh bien, vous pouvez simplement mettre plusieurs "où" clauses directement, mais je ne pense pas que vous voulez. Plusieurs "où" clauses se termine avec une plus restrictive filtre - je pense que vous voulez un moins restrictif. Je pense que vous voulez vraiment:

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();

Notez le && au lieu de ||. Vous souhaitez sélectionner la ligne si le nom d'utilisateur n'est pas XXXX et le nom d'utilisateur n'est pas AAAA.

EDIT: Si vous avez toute une collection, c'est encore plus facile. Supposons que la collection est appelée 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();

Idéalement, vous voulez en faire une HashSet<string> pour éviter l' Contains appel prendre un long moment, mais si la collection est assez petit, il ne fait pas beaucoup d'attente.

48voto

alex Points 121

@Theo

Le traducteur LINQ est assez intelligent pour exécuter:

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

J'ai testé cela dans LinqPad ==> OUI, le traducteur Linq est assez intelligent :))

20voto

@ Jon: Jon, dites-vous en utilisant plusieurs clauses where, par exemple

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

est plus restrictif que d'utiliser

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

Je pense qu'ils sont équivalents en ce qui concerne le résultat.

Cependant, je n'ai pas testé, si vous utilisez plusieurs causes d'emplacement dans le premier exemple dans 2 sous-requêtes, c'est-à-dire .Where(r=>r.UserName!="XXXX").Where(r=>r.UserName!="YYYY) ou si le traducteur LINQ est assez intelligent pour exécuter .Where(r=>r.UserName!="XXXX" && r.UsernName!="YYYY")

6voto

tolpp Points 31

En outre, vous pouvez utiliser la méthode bool

Requête:

 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éthode:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X