Кілька пропозицій WHERE у Linq


75

Я новачок у 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();

Дякую за допомогу заздалегідь !!!

Відповіді:


115

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

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, а ім’я користувача - РРРР.

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тривалого дзвінка, але якщо колекція досить мала, це не буде мати великих шансів.


У мене є колекція UserName. Як динамічно передати його реченню where.
Ганеша

1
Я знаю, що на це було давно дано відповідь, але моя швидка пропозиція полягала б у тому, щоб спробувати використовувати join, а не містити. Набагато ефективніший (особливо якщо ваш набір даних має будь-який розумний розмір).
ArtificialGold

46

@Theo

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

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

Я перевірив це в LinqPad ==> ТАК, перекладач Linq досить розумний :))


Досить розумно означає, що Linq має додаткові фільтри, що є впливом на продуктивність.
Андрес Торо,

20

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


6

Крім того, ви можете використовувати метод (и) 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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.