web-dev-qa-db-fra.com

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 !!!

70
Ganesha

Eh bien, vous pouvez simplement ajouter plusieurs clauses "où" directement, mais je ne pense pas que vous souhaitiez le faire. Plusieurs clauses "where" aboutissent à un filtre plus restrictif - je pense que vous voulez un filtre moins restrictif. Je pense que tu veux 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 voulez sélectionner la ligne si le nom d'utilisateur n'est pas XXXX et le nom d'utilisateur n'est pas YYYY.

EDIT: Si vous avez toute une collection, c'est encore plus facile. Supposons que la collection s'appelle 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 voudriez en faire un HashSet<string> pour éviter que l'appel Contains prenne trop de temps, mais si la collection est suffisamment petite, les chances ne sont pas très grandes.

109
Jon Skeet

@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 :))

39
alex

@ 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 le traducteur LINQ est suffisamment intelligent pour exécuter .Where(r=>r.UserName!="XXXX" && r.UsernName!="YYYY")

19
Theodore Zographos

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;
}
6
Tolga Okur