从DataTable过滤数据

Gop*_*pal 4 c# linq

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

此代码在选定的DataTable中找到值时工作正常,但在DataTable中找不到值时显示错误.所以请告诉我如何检查是否找不到记录.

Tim*_*ter 6

你已经标记了Linq,但是你正在使用DataTable.Select哪种方法来过滤一个DataTable.使用Enumerable.Where和strongyl类型的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();
Run Code Online (Sandbox Code Playgroud)

假设列的类型是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();
}
Run Code Online (Sandbox Code Playgroud)

或者这种方法可能更有效,因为它不需要使用Any,在最坏的情况下会导致额外的完全枚举:

foreach(DataRow row in filteredRows)
{
    tblFiltered.ImportRow(row);
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*eve 5

只需检查您的Select是否返回任何内容?

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

好吧,Tim的Linq例子非常好,但要完成我的答案.如果没有选择行,Select方法也返回Always a DataRow数组,但是你不能要求从这个空数组中构建数据表.想一想.如果数组中没有行,CopyToDataTable应该为结果表构建什么模式?