如何在同一LINQ查询中校验PREM_A或PREM_B的求和非零?
当然可以整合到同一LINQ查询中!
你完全不需要单独用matchRows来做二次筛选,直接把过滤逻辑嵌入到最初的LINQ查询链里就行,这样代码更紧凑,还能避免不必要的内存占用。下面给你两种实现方式:
方式1:先计算求和值,再过滤(性能更优)
这种方式会先把每组的求和结果存下来,避免重复计算两次求和,适合数据量较大的场景:
var resultsDt = dt.AsEnumerable() .GroupBy(row => new { Id = row.Field<string>("ID").Trim() }) // 提前对ID做Trim,减少后续重复操作 .Select(grp => { // 先计算两组求和值,避免后续重复计算 decimal sumPremA = grp.Sum(r => r.Field<decimal>("PREM_A")); decimal sumPremB = grp.Sum(r => r.Field<decimal>("PREM_B")); DataRow newRow = dt.NewRow(); newRow["ID"] = grp.Key.Id; newRow["PREM_A"] = sumPremA; newRow["PREM_B"] = sumPremB; // 返回临时对象,携带求和值用于后续过滤 return new { ResultRow = newRow, SumA = sumPremA, SumB = sumPremB }; }) // 过滤掉求和都为0的行 .Where(item => item.SumA != 0 || item.SumB != 0) // 提取最终需要的DataRow .Select(item => item.ResultRow) .CopyToDataTable(); // 直接遍历处理过滤后的结果即可 foreach (DataRow row in resultsDt.Rows) { // do something }
方式2:先过滤分组,再生成结果行(代码更简洁)
如果你的数据量不大,也可以直接在分组后先过滤掉不符合条件的组,再生成结果行,代码看起来更简洁:
var resultsDt = dt.AsEnumerable() .GroupBy(row => new { Id = row.Field<string>("ID").Trim() }) // 先过滤掉两组求和都为0的分组 .Where(grp => grp.Sum(r => r.Field<decimal>("PREM_A")) != 0 || grp.Sum(r => r.Field<decimal>("PREM_B")) != 0) .Select(grp => { DataRow newRow = dt.NewRow(); newRow["ID"] = grp.Key.Id; newRow["PREM_A"] = grp.Sum(r => r.Field<decimal>("PREM_A")); newRow["PREM_B"] = grp.Sum(r => r.Field<decimal>("PREM_B")); return newRow; }) .CopyToDataTable(); foreach (DataRow row in resultsDt.Rows) { // do something }
小提示
方式2会对每个符合条件的组计算两次求和(一次在Where里,一次在Select里),如果数据量很大的话,方式1的性能会更好;反之,方式2的代码可读性更强,按需选择就好~
内容的提问来源于stack exchange,提问作者User11040
相关产品推荐
相关产品推荐

