LINQ to Entities - 解析/过滤对象集合

3

我正在尝试从我的数据库中筛选用户列表。

当我运行这个LINQ to Entity命令时,它按照我希望的方式工作。它返回所有用户,由txtFilterBy_UserName中的任何内容进行过滤:

(注意,我直接访问了db表。还有几个字段可以过滤,但我在这个例子中只包含了用户名)

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个用户。
3个回答

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),则返回所有用户名中包含该用户的小写用户名的用户,否则(如果未提供筛选值)返回所有小写用户名包含空值(字符串)的用户。


指出奇怪的查询加1。顺便说一下,_users不一定为空 - 它可能没有符合条件的用户。 - Sergey Berezovskiy
我觉得我们有点跑题了,但我想解释一下这行代码应该做什么。(txtFilterBy_UserName(以及其他过滤器)中都有一个水印)如果过滤文本框包含一个值(且该值不是“用户名”),则返回与txtFilterBy_UserName中的值匹配的数据库用户,否则返回所有用户,无论他们是否有用户名... 这是我的完整条件。u.UserName.ToLower().Contains(((txtFilterBy_UserName.Value.Length > 0) && (txtFilterBy_UserName.Value.ToLower() == "username")) ? u.UserName.ToLower() : txtFilterBy_UserName.Value.ToLower()) - wotney

1
看起来你的查询有点混乱。从你的代码来看,我猜你想要做以下操作:
  1. 如果 txtFilterBy_UserName.Value.Length > 0true,那么你只想返回用户名包含txtFilterBy_UserName.Value的用户。基本上你将会进行过滤。
  2. 如果 txtFilterBy_UserName.Value.Length > 0false,那么你想要返回所有用户。这里你不应用任何过滤器。
如果我的猜测是正确的,你可以按以下方式重写你的查询:
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();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接