Множественное предложение WHERE в Linq


Я новичок в LINQ и хочу знать, как выполнить несколько предложений where. Это то, что я хочу достичь: возвращать записи путем фильтрации определенных имен пользователей. Я попробовал код ниже, но не работает, как ожидалось.

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

Спасибо за помощь заранее!!!

4 64

4 ответа:

Ну, вы можете просто поставить несколько "где" предложения непосредственно, но я не думаю, что вы хотите. Несколько предложений "where" заканчиваются на больше ограничительный фильтр - я думаю, что вы хотите меньше ограничительно. Я думаю, что вы действительно хотите:

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

обратите внимание на & & Вместо ||. Вы хотите выбрать строку, если имя пользователя не XXXX и имя пользователя не YYYY.

EDIT: если у вас есть целая коллекция, это еще проще. Предположим, что коллекция называется 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();

В идеале вы хотели бы сделать это HashSet<string> избежать Contains вызов занимает много времени, но если коллекция достаточно мала, это не будет иметь много шансов.

@Theo

переводчик LINQ достаточно умен, чтобы выполнить:

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

Я проверил это в LinqPad ==> Да, переводчик Linq достаточно умен:))

@Jon: Джон, вы говорите, используя несколько предложений where, например

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

является более рестиктивным, чем использование

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

Я думаю, что они эквивалентны как результат идет.

однако я не проверял, если использовать несколько, где в первом примере причина в 2 подзапросах, т. е. .Where(r=>r.UserName!="XXXX").Where(r=>r.UserName!="YYYY) или переводчик LINQ достаточно умен, чтобы выполнить .Where(r=>r.UserName!="XXXX" && r.UsernName!="YYYY")

кроме того, вы можете использовать метод(ы) bool

запрос :

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

способ:

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