使用Linq对数据集进行搜索datatable

4

我有一个用户信息的数据表格。我正在尝试执行搜索,可以使用姓氏、用户ID或用户角色进行搜索。我有一个用于姓名和ID搜索的文本框,以及用于用户角色搜索的下拉菜单。不是所有的都可以留空,但任何组合都可以使用。我正在使用以下内容,但认为它不正确,因为它总是返回整个数据表:

dtUsers.CaseSensitive = false;
var results = dtUsers.AsEnumerable()
    .Where(r => r.Field<String>("LASTNAME").Contains(tbName.Text.Trim())
           ||   r.Field<String>("USERID").Contains(tbUserID.Text.Trim())
           ||   r.Field<String>("USERROLELIST").Contains(ddlRoles.SelectedItem.Text));            

dtUsers = results.CopyToDataTable();

我做错了什么?同时,我还需要能够对姓名和ID进行部分搜索。

1个回答

3

首先使用String.IsNullOrWhiteSpace检查空字符串,然后再应用过滤器,修改您的条件,例如:

var results = dtUsers.AsEnumerable()
    .Where(r =>(!String.IsNullOrWhiteSpace(tbName.Text) && r.Field<String>("LASTNAME").Contains(tbName.Text.Trim())
           || (!String.IsNullOrWhiteSpace(tbUserID.Text) &&r.Field<String>("USERID").Contains(tbUserID.Text.Trim())
           || r.Field<String>("USERROLELIST").Contains(ddlRoles.SelectedItem.Text));

同样,您也可以像处理上一个条件一样来处理最后一个条件,如下所示:
(ddlRoles.SelectedItem != null && 
 !String.IsNullOrWhiteSpace(ddlRoles.SelectedItem.Text) && 
  r.Field<String>("USERROLELIST").Contains(ddlRoles.SelectedItem.Text)

谢谢Habib,它起作用了。它期望完全匹配,所以我将.Contains(...)更改为.IndexOf(...),这样我就可以搜索部分名称或ID。但是,即使我指定了dtUser.CaseSensitive=false,它仍然期望精确的大小写匹配。如果我输入"smi",它不会返回用户"Smith",但"Smi"会返回。 - NoBullMan
对于不区分大小写的包含,使用 IndexOf(tbName.Text, StringComparison.InvariantCultureIgnoreCast) > -1)。参见:https://dev59.com/D3RB5IYBdhLWcg3w-8Lo - Habib
@NoBullMan,就CaseSensitive属性而言,它将在您使用DataTable.Select时使用(CaseSensitive属性会影响排序、搜索和过滤中的字符串比较),但不会影响任何基于LINQ的查询。 - Habib
另一个问题:用户可以拥有多个角色,例如“用户,Helpdesk”。还有一个名为NonRegisteredUser的角色。如果我从下拉列表中选择“用户”角色,则会列出NonRegisteredUsers,因为单词“用户”在其中。有什么方法可以防止这种情况发生吗?我总是可以将角色名称更改为NonRegistered,但这并不是真正的解决方案。 - NoBullMan
不要使用 Contains,而是使用 Equals 还有一种重载形式可以指定不区分大小写的比较。 - Habib

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