2013-06-20 4 views
3

Я пытаюсь отфильтровать список пользователей из моей базы данных.LINQ to Entities - коллекция объектов parse/filter

Когда я запускаю эту команду LINQ to Entity, она работает так, как я надеялся. Она возвращает всех пользователей, фильтруется все, что в txtFilterBy_UserName:

(. Обратите внимание, что я доступ к таблице БД непосредственно Есть также несколько полей для фильтрации, но я включил только имя пользователя в этом примере)

users = db.Users 
      .Where(u => u.IsActive == true && 
         u.UserName.ToLower() 
         .Contains((txtFilterBy_UserName.Value.Length > 0) ? 
            u.UserName.ToLower() : 
            txtFilterBy_UserName.Value.ToLower())) 
      .ToList(); 

... Но в некоторых случаях я уже заселена мою коллекцию пользователя (_users) перед фильтрацией, и я ожидал, чтобы быть в состоянии сделать это:

users = _users.Where(u => u.IsActive == true && 
          u.UserName.ToLower() 
          .Contains((txtFilterBy_UserName.Value.Length > 0) ? 
             u.UserName.ToLower() : 
             txtFilterBy_UserName.Value.ToLower())) 
       .ToList(); 

Но этот метод всегда возвращает 0 пользователей, кто может сказать меня, что я неправильно, или почему этот метод фильтрации пользовательской коллекции не работает?

Скажем, у моей БД есть 100 пользователей, а у 6 из этих пользователей есть символы «john» в их имени пользователя. Когда я напрямую обращаюсь к БД - я возвращаю 6 пользователей. Если объект коллекции пользователей уже заполнен (со 100 пользователями), и я пытаюсь фильтровать коллекцию - 0 пользователей не возвращается

ответ

2

Вместо того, чтобы использовать тройной оператор для фильтрации, просто составить запрос условно добавив Where фильтры:

var query = _users.Where(u => u.IsActive); // don't compare boolean with true 
if (txtFilterBy_UserName.Value.Length > 0) 
    query = query.Where(u => u.UserName.ToLower().Contains(txtFilterBy_UserName.Value.ToLower())); 

var users = query.ToList(); 

И да, я согласен с @Abbas - ваш запрос выглядит штраф. Возможно, у вас нет пользователей, соответствующих вашему состоянию в местной коллекции _users.

+1

Большое спасибо за это решение - я был так отчаянн, чтобы попытаться заставить его работать с таким минимальным кодом, но это имеет больше смысла, и это работает! – wotney

1

Есть ли в коллекции _users какие-либо пользователи вообще (перед фильтрацией)? Кроме того, ваш запрос выглядит странно для меня, пожалуйста, поправьте меня, если я ошибаюсь:

u.UserName.ToLower().Contains((txtFilterBy_UserName.Value.Length > 0) 
           ? u.UserName.ToLower() 
           : txtFilterBy_UserName.Value.ToLower()) 

Я прочитал это как:

Если фильтр-текстовое поле имеет значение (длина> 0) дает мне все пользователи, в которых нижестоящее имя пользователя любого пользователя содержит нижнее имя пользователя этого пользователя, в противном случае (если значение фильтра не предоставляется), дайте мне всех пользователей, где нижнее имя пользователя содержит пустое значение (строка).

+0

+1 за указание на странный запрос. Btw _users не нужно пустым - у него не могло быть условий, соответствующих условию –

+0

Я думаю, что мы немного не по теме, но я хотел бы объяснить, что должна делать эта строка.(txtFilterBy_UserName (и другие фильтры) имеют в них водяной знак). Если текстовое поле фильтра содержит значение (а значение не является «именем пользователя»), тогда верните мне пользователей в db, которые соответствуют значению в txtFilterBy_UserName, иначе верните мне все пользователей, есть ли у них имя пользователя или нет ... Вот мое полное состояние. u.UserName.ToLower(). Содержит (((txtFilterBy_UserName.Value.Length> 0) && (txtFilterBy_UserName.Value.ToLower() == "имя пользователя"))? U.UserName.ToLower(): txtFilterBy_UserName.Value .ToLower()) – wotney

1

Похоже, что у вас немного перепутал ваш запрос. Глядя на ваш код, который я подозреваю, что вы хотите сделать это:

  1. Если txtFilterBy_UserName.Value.Length > 0 это правда тогда вы только хотите, чтобы вернуть пользователям, которые имя пользователя содержит txtFilterBy_UserName.Value. По сути, вы будете делать фильтрацию.
  2. Если txtFilterBy_UserName.Value.Length > 0 is false, тогда вы хотите вернуть всех пользователей. Здесь вы не применяете фильтр.

Если мое предположение верно, то можно переписать запрос следующим образом:

users = db.Users.Where(u => u.IsActive == true); 

if (txtFilterBy_UserName.Value.Length > 0)) 
{ 
    users = users.Where(u => u.UserName.ToLower().Contains(txtFilterBy_UserName.Value.ToLower())); 
} 

users = users.ToList();