从DataTable中筛选数据

4
DataTable dtt = (DataTable)Session["ByBrand"];
var filldt = (dtt.Select("Price >= " + HiddenField1.Value + " and Price <= " + HiddenField2.Value + "")).CopyToDataTable();

当选择的DataTable中存在值时,此代码可以正常运行,但是当DataTable中找不到值时,会出现错误。因此,请告诉我如何检查是否没有记录。


你遇到了什么错误?似乎 CopyToDataTable() 扩展方法应该返回一个空的 DataTable,即使结果为空也不会出错。 - Ocelot20
2个回答

6

只需检查您的选择器是否返回任何内容即可?

 DataTable dtt = (DataTable)Session["ByBrand"];
 DataRow[] rows = dtt.Select("Price >= " + HiddenField1.Value + " and Price <= " + HiddenField2.Value + "");
if(rows.Length > 0)
{
    var filldt = rows.CopyToDataTable();
}

嗯,Tim的Linq示例确实不错,但为了完整回答问题。

Select方法始终返回DataRow数组,即使没有选择任何行,但是您不能要求从此空数组构建数据表。想想看。如果数组中没有行,则CopyToDataTable应该为生成的表构建什么模式?


6
你标记了 Linq,但是你正在使用过时的方法 DataTable.Select 过滤 DataTable。请使用 Enumerable.Where 和强类型 Field 扩展方法。
decimal priceFrom = decimal.Parse(HiddenField1.Value);
decimal priceTo = decimal.Parse(HiddenField2.Value);

var dtFiltered = dtt.AsEnumerable()
    .Where(row => row.Field<decimal>("Price") >= priceFrom 
               && row.Field<decimal>("Price") <= priceTo))
    .CopyToDataTable();

假设列的类型为decimal,如果是不同的类型,则需要在Field中使用该类型或先进行转换。
请注意,您需要添加System.Linq(文件)和对System.Data.DataSetExtensions(项目)的引用。 更新

但当DataTable中没有找到值时,它会显示错误

如果输入序列为空,则CopyToDataTable会抛出异常。我认为最好的方法是单独处理这种情况。
DataTable tblFiltered = dtt.Clone(); // clones only structure not data
var filteredRows = dtt.AsEnumerable()
    .Where(row => row.Field<decimal>("Price") >= priceFrom 
               && row.Field<decimal>("Price") <= priceTo));
if(filteredRows.Any())
{
    tblFiltered = filteredRows.CopyToDataTable();
}

或者采用这种更有效的方法,因为它不需要使用Any,在最坏情况下可能会导致额外的完全枚举:
foreach(DataRow row in filteredRows)
{
    tblFiltered.ImportRow(row);
}

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