如何使用lambda表达式过滤DataRows?

14

如何在datatable中查找Col1="MyValue"的行?

我想的是:

Assert.IsTrue(dataSet.Tables[0].Rows.
    FindAll(x => x.Col1 == "MyValue" ).Count == 1);

但是当然那样行不通!


你想返回匹配的行,还是只想得到有多少行? - Dan Diplo
5个回答

26

你可以使用 LINQ to DataSets 来实现:

Assert.IsTrue(dataSet.Tables[0].AsEnumerable().Where(
    r => ((string) r["Col1"]) == "MyValue").Count() == 1);

请注意,您也可以在不调用Assert的情况下完成这个操作:

dataSet.Tables[0].AsEnumerable().Where(
    r => ((string) r["Col1"]) == "MyValue").Single();

如果行数不等于1(因此调用了Single),则会引发异常,该未处理的异常应该导致测试用例失败。就我个人而言,我更喜欢后者,因为它具有更清晰的语义意义。

以上内容可以进一步简化为:

dataSet.Tables[0].AsEnumerable().Single(
    r => ((string) r["Col1"]) == "MyValue");

此外,您可以利用Field方法DataRowExtensions上,以简化对字段的类型安全访问(同时提供了将DBNull转换为.NET中的空值的额外好处):

dataSet.Tables[0].AsEnumerable().Single(
    r => r.Field<string>("Col1") == "MyValue");

7
你可以使用数据表的 Select 方法或者表上 DefaultDataView 的过滤属性来实现此功能。
对于 Select 方法:
var rows = dataSet.Tables[0].Select("Col1 = 'MyValue'");

对于DefaultView过滤器:

dataSet.Tables[0].DefaultView.Fitler = "Col1 = 'MyValue'";
foreach (var drv in dataSet.Tables[0].DefaultView)
{
    // Do your processing
}

1
这可能不是提问者正在寻找的,但我认为它很有帮助。 - twip

4
为什么要使用 lambda 而不是 select
  DataRow[] foundRow = ( dataSet.Tables[0].Rows.Select("Col1 = 'MyValue'");

应该只有一个等号 - JWiley

3
你可以尝试这个方法:
var b=datatable.AsEnumerable.where(p=> p.Field<string>   
("column_name")=="desire_value").CopyToDataTable()

0

你编写的代码检查了只有一行符合你的搜索条件。 如果你实际上需要这些行,请删除 AssertCount


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