wake-up-neo.com

Mehrfache WHERE-Klausel in Linq

Ich bin neu in LINQ und möchte wissen, wie man eine multiple where-Klausel ausführt. Folgendes möchte ich erreichen: Datensätze durch Herausfiltern bestimmter Benutzernamen zurückgeben. Ich habe den folgenden Code ausprobiert, aber nicht wie erwartet funktioniert.

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

Danke für die Hilfe im Voraus !!!

70
Ganesha

Nun, Sie können einfach mehrere "where" -Klauseln direkt einfügen, aber ich glaube nicht, dass Sie dies möchten. Mehrere "where" -Klauseln führen zu einem mehr einschränkenden Filter - ich denke, Sie möchten einen weniger einschränkenden Filter. Ich denke du willst wirklich:

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

Beachten Sie das && anstelle von ||. Sie möchten die Zeile auswählen, wenn der Benutzername nicht XXXX ist nd der Benutzername ist nicht JJJJ.

EDIT: Wenn Sie eine ganze Sammlung haben, ist es noch einfacher. Angenommen, die Sammlung heißt 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();

Idealerweise möchten Sie dies zu einem HashSet<string> Machen, um zu vermeiden, dass der Aufruf von Contains lange dauert, aber wenn die Sammlung klein genug ist, wird dies keine großen Chancen haben.

109
Jon Skeet

@Theo

Der LINQ-Übersetzer ist intelligent genug, um Folgendes auszuführen:

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

Ich habe dies in LinqPad getestet ==> JA, der Linq-Übersetzer ist schlau genug :))

39
alex

@ Jon: Jon, sagst du, dass du mehrere where-Klauseln verwendest, z.

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

ist restriktiver als mit

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

Ich denke, dass sie in Bezug auf das Ergebnis gleichwertig sind.

Ich habe jedoch nicht getestet, ob bei der Verwendung von Mehrfachnachrichten im ersten Beispiel Ursache in 2 Unterabfragen ist, d. H. .Where(r=>r.UserName!="XXXX").Where(r=>r.UserName!="YYYY) oder der LINQ-Übersetzer ist intelligent genug, um .Where(r=>r.UserName!="XXXX" && r.UsernName!="YYYY") auszuführen.

19

Sie können auch bool-Methoden verwenden.

Abfrage:

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

Methode:

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