将平面查询转换为二维 table

Turn flat query into 2D table

我有一个数据库 table,其中每一行都有(除其他外)日期、产品和数量字段:

Date       Prod Qty
06/01/2018 ABC 10
06/02/2018 ABC 5
06/03/2018 ABC 3
...
06/01/2018 DEF 2
06/02/2018 DEF 8
06/03/2018 DEF 11
...
06/01/2018 GHI 1

我想输出按日期和产品分组的 2D table:

            ABC DEF GHI
06/01/2018  10  2    1
06/02/2018  5   8    2
06/03/2018  3   11   4

我可以看到一种丑陋且非 LINQ-y 的方式来执行此操作(找到不同的日期和产品列表,制作一个尺寸与这些列表匹配的二维数组,手动遍历列表以找到与那行和那列。)但是还有更优雅的东西吗?

产品数量很多,因此手动加入一堆查询似乎不可行。

像下面的代码一样创建一个枢轴table:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication1
{
    public class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Date", typeof(DateTime));
            dt.Columns.Add("Prod", typeof(string));
            dt.Columns.Add("Qty", typeof(int));

            dt.Rows.Add(new object[] {DateTime.Parse("06/01/2018"), "ABC", 10});
            dt.Rows.Add(new object[] {DateTime.Parse("06/02/2018"), "ABC", 5});
            dt.Rows.Add(new object[] {DateTime.Parse("06/03/2018"), "ABC", 3});
            dt.Rows.Add(new object[] {DateTime.Parse("06/01/2018"), "DEF", 2});
            dt.Rows.Add(new object[] {DateTime.Parse("06/02/2018"), "DEF", 8});
            dt.Rows.Add(new object[] {DateTime.Parse("06/03/2018"), "DEF", 11});
            dt.Rows.Add(new object[] {DateTime.Parse("06/01/2018"), "GHI", 1});

            string[] uniqueProducts = dt.AsEnumerable().Select(x => x.Field<string>("Prod")).OrderBy(x => x).Distinct().ToArray();

            DataTable pivot = new DataTable();
            pivot.Columns.Add("Date", typeof(DateTime));
            foreach (string prod in uniqueProducts)
            {
                pivot.Columns.Add(prod, typeof(int));
            }

            var groups = dt.AsEnumerable().OrderBy(x => x.Field<DateTime>("Date")).GroupBy(x => x.Field<DateTime>("Date").Date).ToList();

            foreach(var group in groups)
            {
                DataRow newRow = pivot.Rows.Add();
                newRow["Date"] = group.Key;
                foreach (DataRow row in group)
                {
                    newRow[row.Field<string>("Prod")] = row.Field<int>("Qty");
                }
            }
        }
    }
}