2009-03-24 3 views
60

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

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

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

ответ

98

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

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

+0

У меня есть коллекция UserName. Как передать его в предложение where динамически. – Ganesha

+1

Я знаю, что на это был дан ответ давным-давно, но мое быстрое предложение было бы попытаться использовать соединение, а не содержать. Это намного эффективнее (особенно если ваш набор данных имеет разумный размер). – ArtificialGold

17

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

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

более restictive, чем при использовании

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

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

Запрос:

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; 
} 
28

@Theo

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

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

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

Смежные вопросы