【问题标题】:Linq Convert or Pivot Rows to Columns [duplicate]Linq将行转换或透视到列[重复]
【发布时间】:2016-01-22 02:13:47
【问题描述】:

我从查询中返回了以下数据:

+-------------------------------------+
| **SUM**                 **Account** |
+-------------------------------------+
| A & E FEE           182396          |
| CM FEE              108569          |
| CONTRACT VALUE      2256044         |
| OVERHEAD            197397          |
+-------------------------------------+   

我需要在对象 Properties AeFee、CmFee、ContractValue 和 Overhead 中进行选择,这实际上会使属性成为列标题,因此我需要数据如下所示:

+--------+--------+---------------+----------+
| AeFee  | CmFee  | ContractValue | Overhead |
+--------+--------+---------------+----------+
| 182396 | 108569 |       2256044 |   197397 |
+--------+--------+---------------+----------+      

我尝试使用子选择来选择类似这样的内容(伪代码)

Select(s => new
{
   AeFee = Sum if [Account] == "A & E FEE"
}

此链接准确地显示了我正在尝试使用 SQL 数据透视表执行的操作。将行转换为列。 SQL Pivot

有什么想法吗?

【问题讨论】:

  • 或许将其转换为Dictionary<string,int> 会更有意义?
  • 另外,您是否已经知道属性名称?还是必须是动态的?如果您已经有一个具体的类要映射到,那么这个答案可能有用:stackoverflow.com/questions/4943817/…
  • 你说I need the data to look like,为什么?
  • @RobertMcKee 我有一个 MVC ViewModel,其中行由 ViewModel 中的属性表示。我需要在我的页面上的网格中显示这个 ViewModel,所以我确实需要数据以问题所示的形式查看(成形)。

标签: c# linq


【解决方案1】:

这产生了我正在寻找的结果

var accounts = new List<string>()
                       {
                           "A & E FEE",
                           "cm fee",
                           "contract value",
                           "overhead"
                       };

        var commission = PJPTDSUMs
            .Where(p => p.Project.StartsWith("b29317")
                        && accounts.Contains(p.Acct)
                        && !p.Pjt_entity.StartsWith("05"))
            .GroupBy(c => c.Project)
            .Select(g => new
                         {
                             AeFee = g.Where(p => p.Acct == "A & E FEE").Sum(s => s.Eac_amount),
                             CmFee = g.Where(p => p.Acct == "cm fee").Sum(s => s.Eac_amount),
                             ContractValue = g.Where(p => p.Acct == "contract value").Sum(s => s.Eac_amount),
                             Overhead = g.Where(p => p.Acct == "overhead").Sum(s => s.Eac_amount),
                         });


+--------+--------+---------------+----------+
| AeFee  | CmFee  | ContractValue | Overhead |
+--------+--------+---------------+----------+
| 182396 | 108569 |       2256044 |   197397 |
+--------+--------+---------------+----------+

【讨论】:

    【解决方案2】:

    我总是喜欢答案是聚合的问题。

      var result = data.Aggregate(
        // base object to store
        new { A = 0, CM = 0, CO = 0, O = 0},
        // add in an element
        (a,d) => {
        switch(d.sum) 
          {
             case "A & E FEE": 
               a.A += d.Account;
               break;
             case "CM FEE": 
               a.CM += d.Account;
               break;
               //etc
          }
          return a;
      });
    

    请注意,您也可以 - 以这种方式不知道 d.sum 的可能值 - 您需要使用和 expando 对象。看起来像这样(未测试)

      var result = data.Aggregate(
        // base object to store
        new ExpandoObject()
        // add in an element
        (a,d.sum.Replace(" ","_") => {
          a[d.sum.Replace(" ","_")] += d.Account;
          return a;
      });
    

    如果您的总和字符串包含在属性标识符中无效的值,这将不起作用。

    【讨论】:

    • 你检查过 EF Core 为此生成了什么吗?
    • @DmitriBodiu -- 不,因为这个问题与 EF 无关
    猜你喜欢
    • 1970-01-01
    • 2013-07-29
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 1970-01-01
    • 2017-06-28
    • 2021-10-25
    • 1970-01-01
    相关资源
    最近更新 更多