动态 LINQ - 与分组依据/选择语法作斗争

本文关键字:选择 语法 斗争 LINQ 动态 | 更新日期: 2023-09-27 18:31:41

我有一组重复的数据,我正在从多个SQL表中检索这些数据(长话短说,尽管具有相同的数据,但它们都有不同的名称)检索到.NET DataTable中:

Point_Date  ->  Point_Value0  ->  Point_Value1  ->  Point_Value2  ->  Point_ValueX  
24/11/2014 16:18:07  ->  15.1  ->  NULL  ->  NULL  
24/11/2014 16:19:07  ->  15.2  ->  NULL  ->  NULL  
24/11/2014 16:20:07  ->  15.3  ->  NULL  ->  NULL  
24/11/2014 16:18:07  ->  NULL  ->  16.1  ->  NULL  
24/11/2014 16:19:07  ->  NULL  ->  16.2  ->  NULL  
24/11/2014 16:20:07  ->  NULL  ->  16.3  ->  NULL  
24/11/2014 16:18:07  ->  NULL  ->  NULL  ->  17.1  
24/11/2014 16:19:07  ->  NULL  ->  NULL  ->  17.2  
24/11/2014 16:20:07  ->  NULL  ->  NULL  ->  17.3

我想使用 LINQ 对日期/时间字段上的数据进行分组,以便最终得到如下记录:-

2014-11-24 16:18:07 -> 15.1 -> 16.1 -> 17.1

我的问题是我不知道会有多少组数据(示例中有三组,但可能有任何数量),所以我需要使用动态 LINQ。

对于固定数量的字段,我可以进行LINQ查询:-

var dtReport = (from row in dtPoints.AsEnumerable()
                group row by row.Field<DateTime>("Point_Date")
                        into t
                        select new
                        {
                        TempDate = t.Key,
                        Value1 = (double?) t.Sum(r => r.Field<double?>("Point_Value0") ?? 0),
                        Value2 = (double?)t.Sum(r => r.Field<double?>("Point_Value1") ?? 0),
                        Value3 = (double?)t.Sum(r => r.Field<double?>("Point_Value2") ?? 0)
                        });

但是我真的很努力使用它使用System.Linq.Dynamic使其动态,以下给了我一个错误:-

        var myRpt2 = dtPoints.AsEnumerable()
            .AsQueryable()
            .GroupBy("new ( it['"Point_Date'"] as GrpByCol1)", "it")
            .Select("new (it.key as TempDate, it.sum('"Point_Value0'") as SumValue)");
  • 错误是:-

System.Linq.Dynamic.ParseException{"不存在适用的聚合方法'总和'"}

完成

GroupBy 后,我只是不知道如何引用"Point_Value"字段 - 根据数据集的数量,会有多个"sum(Point_ValueX)"字段,但我什至无法让它适用于单个字段目前!

非常感谢,

大卫。

动态 LINQ - 与分组依据/选择语法作斗争

我认为你不能那样完成它。动态 linq 似乎无法分析包含索引器的表达式。

但是,您可以使用动态 LINQ 和常规 LINQ 的组合:

var myRpt2 = (
        dtPoints.AsEnumerable()
        .AsQueryable()
        .GroupBy("new ( it['"Point_Date'"] as GrpByCol1)", "it")
        as IEnumerable<IGrouping<DynamicClass,DataRow>>
    )
    .Select (r => new { ((dynamic)r.Key).GrpByCol1, 
                        Sum = r.Sum(x => x.Field<decimal>("Point_Value0"))});

主要的转折是GroupBy结果对IEnumerable<IGrouping<DynamicClass,DataRow>>的投射。