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

C# 如何使用LINQ生成透视数据?,c#,linq,C#,Linq,在将此作为副本关闭之前,请注意,我知道关于“”有许多问题,我花了一整天的时间试图解决这些问题,直到现在才转向解决这些问题 我从数据库中以这种形式获取数据: Item Collection_Period Value ==== ================= ===== Item3 201307 27.2 Item4 201308 19 Item3 201209 2.1 Item2

在将此作为副本关闭之前,请注意,我知道关于“”有许多问题,我花了一整天的时间试图解决这些问题,直到现在才转向解决这些问题

我从数据库中以这种形式获取数据:

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;
MeanData类的定义:

public class MeanData
{
    public string Description { get; set; }
    public long SeqNo { get; set; }
    public string CollectionPeriod { get; set; }
    public long Value { get; set; }
}
我搜索了很多,发现完全符合我的挑战。但是,如果我在代码未编译的Where谓词末尾添加
。选择(c=>c.Value)
(因为我只需要该时段的值)

“char”不包含“Value”的定义

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


我做错了什么?我的尝试是完全错误的还是仅仅获取
值是错误的?

您尝试过这样做吗

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

因为您正在对正在枚举该字符串中的字符的字符串调用
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)  

虽然我从拉斐尔的回答中猜出了答案,但我喜欢你的解释。这对我来说不起作用,但帮助我找到了答案。我尝试了
g.Where(predicate).FirstOrDefault().Value.ToString()
,结果成功了。很抱歉,您必须在FirstOrDefault之后指定字段。如果您尝试在不使用ToString()的情况下执行此操作,则不需要强制转换。糟糕的是,我忘了更改类定义。M3、M2和M1实际上是字符串。谢谢你指出这一点。我编辑了这个问题。
M3 = g.Where(c => DateTime.ParseExact(c.CollectionPeriod, 
                                      "yyyyMM", 
                                      CultureInfo.InvariantCulture)
                          .Month == thisMonth - 3)
      .Sum(c => c.Value)