在列中过滤具有多个值的数据表行

问题描述

我有一个包含多列的 DataTable (dt),它是 DataGridView 的源。我正在尝试使用特定列的值列表过滤此 DataTable(dt)。

我需要使用员工姓名列表过滤下面的数据表(dt)。 EmpList = {'Pete','Alen'}

这是我的数据表

员工 ID 国家
皮特 1 美国
标记 2 英国
艾伦 3 澳大利亚

需要输出

员工 ID 国家
皮特 1 美国
艾伦 3 澳大利亚

我正在尝试使用以下代码

if (EmpList.Any())
{
  foreach(string item in EmpList)
  {
    var daTarows = from daTarow in dt.AsEnumerable()
                   where (daTarow.Field<string>("Employee").Contains(item))
                   select daTarow;

    dt.Rows.Add(daTarows);
  }
}

问题是在这代码中,DataType(System.Data.EnumerableRowCollection[system.Data.DaTarow]) 与之前的数据一起填充了 DataTable 的 Rows。

解决方法

如果要过滤DataTable,可以使用DefaultView.RowFilter,加入要比较的值的集合,在比较中使用IN()运算符:

var names = new[]{ "Allen","Pete" };
var values = string.Join("','",names);
dt.DefaultView.RowFilter = $"Employee IN('{values}')";

请注意,字符串使用逗号和单引号连接:','
要移除过滤器,只需将其设置为 string.Empty

如果要返回一个新的DataTable,可以使用CopyToDataTable方法:

var dtFiltered = dt.AsEnumerable()
    .Where(dr => names.Any(s => s.Equals(dr["Employees"]))).CopyToDataTable();

您也可以将 DataTable 分配给自身:

dt = dt.AsEnumerable().Where(...).CopyToDataTable();

我假设您已经在引用 System.Data.DataSetExtensions,因为您在代码中使用了 AsEnymerable()