You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用LINQ对DataTable分组排序去重并解决匿名类型声明异常

错误原因

你的代码存在两个明确的语法错误,以及一个潜在的业务逻辑问题:

  • group by 子句的匿名类型未显式声明属性名,C# 无法从Field<T>方法调用自动推导匿名类属性名,必须手动指定。
  • 分组后的组内集合变量名是g,你子查询中使用的groupedItems属于未定义变量,直接遍历g即可获取组内所有行。
  • 潜在问题:当前Col3存储的是字符串格式的数字,直接按字符串排序会出现"10" < "2"的不符合预期的结果,建议转成数值类型排序。
修复后的代码

查询语法写法

var result = from record in datatable.AsEnumerable()
             group record by new 
             { 
                 Col1 = record.Field<string>("Col1"), 
                 Col2 = record.Field<string>("Col2") 
             } into g
             // 组内按Col3数值降序,取第一条
             let targetRow = g.OrderByDescending(row => int.Parse(row.Field<string>("Col3"))).First()
             select targetRow;

// 若需要转回DataTable直接调用CopyToDataTable即可
// DataTable resultTable = result.CopyToDataTable();

流式写法

var result = datatable.AsEnumerable()
    .GroupBy(row => new 
    {
        Col1 = row.Field<string>("Col1"),
        Col2 = row.Field<string>("Col2")
    })
    .Select(g => g.OrderByDescending(row => int.Parse(row.Field<string>("Col3"))).First());
优化建议

如果Col3本身就是数值类型,建议在初始化DataTable时就指定列类型,避免后续频繁类型转换:

// 初始化时指定Col3为int类型
datatable.Columns.Add("Col3", typeof(int));
// 赋值时直接传入数值
row1.ItemArray = new object[] { "A", "B", 1 };

修改后排序时不需要再做字符串转int的操作,直接写row.Field<int>("Col3")即可。

自定义规则扩展

你可以任意修改组内选行的逻辑满足不同业务需求:

  • 保留Col3最小的行:将OrderByDescending改为OrderBy
  • 保留符合特定条件的行:将排序逻辑替换为Where条件,比如g.First(row => row.Field<string>("Col3") == "1")

内容的提问来源于stack exchange,提问作者Muflix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 04:45:03