如何使用LINQ生成数据透视数据?

时间:2013-10-18 12:50:00

标签: c# linq

在关闭此内容之前,请注意我知道“[c#] [linq] pivot”上有很多问题,我花了一整天的时间来解决这个问题,现在才转向SO。

我从数据库中获取此表单中的数据:

Item    Collection_Period   Value
====    =================   =====
Item3       201307          27.2
Item4       201308          19
Item3       201209          2.1
Item2       201307          345
Item1       201309          13.11
Item2       201308          34
Item3       200609          85
Item4       201308          58.2
Item3       201209          2.4
Item2       201309          12.1
Item1       201209          12.3

我需要将数据操作为这种格式:

Item    CurrMon-3   CurrMon-2   CurrMon-1
=====   =========   =========   =========
Item1                           13.11
Item2   345         34          12.1
Item3   27.2
Item4   19          58.2

(仅需要显示最近三个月的数据)。我正在尝试这个:

var pivoted = new List<PivotedMeanData>();
var thisMonth = DateTime.Now.Month;
var p = meanData
    .GroupBy(i => i.Description)
    .Select(g => new PivotedMeanData
    {
        Description = g.Key,
        M3 = g.Where(c => DateTime.ParseExact(c.CollectionPeriod, "yyyyMM", CultureInfo.InvariantCulture).Month == thisMonth - 3).ToString().Select(c => c.Value),
        M2 = g.Where(c => DateTime.ParseExact(c.CollectionPeriod, "yyyyMM", CultureInfo.InvariantCulture).Month == thisMonth - 2).ToString().Select(c => c.Value),
        M1 = g.Where(c => DateTime.ParseExact(c.CollectionPeriod, "yyyyMM", CultureInfo.InvariantCulture).Month == thisMonth - 1).ToString().Select(c => c.Value)
    });
return pivoted;

我有一个班级来保存这些数据:

public class PivotedMeanData
{
    public string Description { get; set; }
    public string M3 { get; set; }
    public string M2 { get; set; }
    public string M1 { get; set; }
}

MeanData类的定义:

public class MeanData
{
    public string Description { get; set; }
    public long SeqNo { get; set; }
    public string CollectionPeriod { get; set; }
    public long Value { get; set; }
}

我搜索了很多,发现this question与我的挑战完全匹配。但是,如果我在Where谓词的末尾添加.Select(c => c.Value)(因为我只需要那段时间的值)代码没有编译。

  

'char'不包含'Value'的定义

引用的问题显示完全相同的事情(他们只使用了sum而不是select)

我在这里做错了什么?我的尝试是完全错误还是只是让Value错了?

2 个答案:

答案 0 :(得分:4)

因为您在枚举该字符串中的字符的字符串上调用Select()

M3 = g.Where(c => DateTime.ParseExact(c.CollectionPeriod, 
                                      "yyyyMM", 
                                      CultureInfo.InvariantCulture)
                          .Month == thisMonth - 3)
      .ToString()      // string
      .Select(c => c.Value)  //c = char

我怀疑你想要

M3 = g.Where(c => DateTime.ParseExact(c.CollectionPeriod, 
                                      "yyyyMM", 
                                      CultureInfo.InvariantCulture)
                          .Month == thisMonth - 3)
      .Sum(c => c.Value)  

答案 1 :(得分:3)

你尝试过这样的事吗?

g.Where(c => DateTime.ParseExact(c.CollectionPeriod, "yyyyMM", CultureInfo.InvariantCulture).Month == thisMonth - 3).Select(c => c.Value).FirstOrDefault();