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

Я новичок в LINQ и хочу знать, как выполнять предложение multiple 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();

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

Ответ 1

Ну, вы можете просто добавить несколько предложений "where", но я не думаю, что вы этого хотите. Несколько предложений "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, занимающего много времени, но если коллекция достаточно мала, это не будет иметь больших шансов.

Ответ 2

@Theo

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

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

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

Ответ 3

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

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")

Ответ 4

Кроме того, вы можете использовать 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;
}