使用LINQ透视表式结果

本文关键字:结果 透视 LINQ 使用 | 更新日期: 2023-09-27 18:20:11

在LINQ中有什么方法可以做到这一点吗?我已经对此进行了一段时间的思考:

来源:

var selectedDate = new DateTime(2013, 1, 1);
var selectedMonth = selectedDate.Month;
var selectedYear = selectedDate.Year;
var data = new List<MyClass>
{
    new MyClass { Date = new DateTime(2013, 1, 1), Val1 = 1, Val2 = 2 },
    new MyClass { Date = new DateTime(2013, 1, 2), Val1 = 1, Val2 = 2 },
    new MyClass { Date = new DateTime(2013, 2, 1), Val1 = 1, Val2 = 2 }
};
Date       | Val1 | Val2
01/01/2013 | 1    | 2
02/01/2013 | 1    | 2
01/02/2013 | 1    | 2

结果(每个Val与日期/月/年的总和):

     | selectedDate | selectedMonth | selectedYear
Val1 | 1            | 2             | 3
Val2 | 2            | 4             | 6

使用LINQ透视表式结果

我真的不认为LINQ是解决方案。你可以很容易地得到一个单轴的"行",但你需要再次枚举序列才能得到下一个,这不是很有效(如果源是一个"懒惰"的可枚举对象,并且你不想把整个序列保存在内存中,这也不起作用)。

我认为最简单、有效的解决方案是标准的foreach。如果必须的话,你可以使用Aggregate将其转换为LINQ,但它不会那么简单:

        var val1 = new Result();
        var val2 = new Result();
        foreach (var item in data) {
            if (item.Date == selectedDate) {
                val1.Date += item.Val1;
                val2.Date += item.Val2;
            }
            if (item.Date.Month == selectedMonth) {
                val1.Month += item.Val1;
                val2.Month += item.Val2;
            }
            if (item.Date.Year == selectedYear) {
                val1.Year += item.Val1;
                val2.Year += item.Val2;
            }
        }

可能有一些方法可以使其更具活力,但这是另一个问题。

var result = new List<Result>{
    new Result{
      Val = "Val1",
      Date = data.Sum(e => e.Val1 * (e.Date == selectedDate ? 1 : 0)),
      Month = data.Sum(e => e.Val1 * (e.Date.Month == selectedMonth ? 1 : 0)),
      Year = data.Sum(e => e.Val1 * (e.Date.Year == selectedYear ? 1 : 0)),
    },
    new Result{
      Val = "Val2",
      Date = data.Sum(e => e.Val2 * (e.Date == selectedDate ? 1 : 0)),
      Month = data.Sum(e => e.Val2 * (e.Date.Month == selectedMonth ? 1 : 0)),
      Year = data.Sum(e => e.Val2 * (e.Date.Year == selectedYear ? 1 : 0)),
    }
};

Result:

public class Result {
    public String Val { get; set; }
    public int Date { get; set; }
    public int Month { get; set; }
    public int Year { get; set; }
}