首页 > 解决方案 > 使用 Linq 转置自定义集合

问题描述

我有一个对象的 BindingList,每个对象都有一个嵌套的项目列表。

BindingList<QuoteboardRow> quoteboard = new BindingList<QuoteboardRow>();
quoteboard.Add(
    new QuoteboardRow()
    {
        Product= "Cement",
        Prices = new Dictionary<string, Price>() {
            { "SupplierA",
                new Price() { Low= 101, High= 102 }
            },
            { "SupplierB",
                new Price() { Low= 101, High= 102 }
            },
            { "SupplierC",
                new Price() { Low= 101, High= 102 }
            }
    }
);
dataGridView1.DataSource = quoteboard;

如果我只是将集合数据绑定到 datagridview,这就是我所看到的:

在此处输入图像描述

我想尝试转置该集合,以便它为每个供应商提供一个列,并分别为低价格和高价格提供一个子列。基本上,就像一个为每个供应商提供一列的报价板,或者如果默认的 datagridview 支持某种分组:每个供应商的低价和高价的子栏。我手动填充了一些 datagridview 单元格显示了我想要实现的目标:

在此处输入图像描述

我一直在尝试使用如下代码片段取得进展,但无济于事。

var result = quoteboard
.SelectMany(x => x.Prices.Select((item, index) => new { Source = x.Product, item, index  }))
.GroupBy(i => i.index)
.Select(g => g.ToList())
.ToList();

对于这方面的任何帮助,我将不胜感激。如果有更好的数据绑定 datagridview 和集合的方法,datagridview 是只读的,我将更新集合以反映价格的任何变化。

标签: c#linqdata-bindingcollectionspivot-table

解决方案


您可以尝试使用将 QuoteboardRow 的每个项目转换为新类型并将每个价格列为单个项目的方法。

对于要以“转置”方式打印的每个项目,您必须获取一个对象并将其转换为与产品/名称相同的格式...Dictionary<string, object>

将项目转换为字典的方法

    public static Dictionary<string, object> ConvertItemToDictionary(QuoteboardRow x)
    {
        Dictionary<string, object> result = new Dictionary<string, object>();
        result.Add("Product", x.Product);
        foreach (var key in x.Prices.Keys)
        {
            x.Prices.TryGetValue(key, out Price price);
            result.Add($"{key}_L", price.Low);
            result.Add($"{key}_H", price.High);
        }
        return result;
    }

在您的主要或其他过程中使用它,

    BindingList<QuoteboardRow> quoteboard = new BindingList<QuoteboardRow>();
    quoteboard.Add(
        new QuoteboardRow()
        {
            Product = "Cement",
            Prices = new Dictionary<string, Price>() 
            {
                { "SupplierA",
                    new Price() { Low= 101, High= 102 }
                },
                { "SupplierB",
                    new Price() { Low= 101, High= 102 }
                },
                { "SupplierC",
                    new Price() { Low= 101, High= 102 }
                }
            }
        }
    );

    var result = quoteboard.Select(x => ConvertItemToDictionary(x)).ToList();


    Console.WriteLine(JsonConvert.SerializeObject(result, Formatting.Indented));
    dataGridView1.DataSource = result;

在控制台中,我将此作为输出,这将以转置方式正确打印。(我添加了支柱作为测试的第二个条目)

[
  {
    "Product": "Cement",
    "SupplierA_L": 101,
    "SupplierA_H": 102,
    "SupplierB_L": 101,
    "SupplierB_H": 102,
    "SupplierC_L": 101,
    "SupplierC_H": 102
  },
  {
    "Product": "pillar",
    "SupplierA_L": 101,
    "SupplierA_H": 104,
    "SupplierB_L": 101,
    "SupplierB_H": 101,
    "SupplierC_L": 101,
    "SupplierC_H": 105
  }
]

推荐阅读