如何使用linq树表达式创建具有动态列的数据透视表

时间:2011-02-08 00:17:38

标签: c# asp.net linq linq-to-dataset over-clause

我正在编写一个asp.net C# Web应用程序; 我有一个名为“table1”的内存数据表有三列“country”,“productId”和“productQuantity”; 我想转动该表以获得一个新表(假设“table2”),其中第一列“country”为固定列,动态数字和列名称为{{1 }','product_1',...,'product_2'根据“product_n”中存在的产品总数; 第一列“table1”必须包含国家/地区名称; 动态生成的列“country”,“product_1”,...,“product_2”必须包含已为指定的每个特定产品选择的product_n国家

我正在使用Linq查询表达式来编写代码;问题是我不能硬编码名称和产品的价值;我无法预测数据表中存在多少产品; 现在,我正在使用以下表达式测试结果:

productQuantity

我举例说明'var query = table1.AsEnumerable() .GroupBy(c => c.country) .Select(g => new { country = g.Key, product_1 = g.Where(c => c.productId == "a30-m").Select(c => c.productQuantity).FirstOrDefault(), product_2 = g.Where(c => c.productId == "q29-s").Select(c => c.productQuantity).FirstOrDefault(), . . . product_n = g.Where(c => c.productId == "g33-r").Select(c => c.productQuantity).FirstOrDefault() }); '的外观以及'table1'的外观如何:

view example image of the two tables table1 and table2

任何人都可以帮我找到使用linq树表达式或其他linq方法创建带动态列的数据透视表的解决方案; 任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

无法在sql中查询动态数量的列。通过扩展,不可能使用linq,因为它基于sql。

所以你运气不好,抱歉。

但是,您可以从{country, product}服务器请求所有现有的sql对,并在客户端上执行剩余的处理(通过执行.Select(x => x.product).Distinct()等重建国家和产品,然后动态在数据网格中创建列。)

答案 1 :(得分:0)

我一直在使用此扩展程序进行数据透视列表。

 public static Dictionary<TFirstKey, Dictionary<TSecondKey, TValue>> Pivot<TSource, TFirstKey, TSecondKey, TValue>(this IEnumerable<TSource> source, Func<TSource, TFirstKey> firstKeySelector, Func<TSource, TSecondKey> secondKeySelector, Func<IEnumerable<TSource>, TValue> aggregate)
    {
        var retVal = new Dictionary<TFirstKey, Dictionary<TSecondKey, TValue>>();

        var l = source.ToLookup(firstKeySelector);
        foreach (var item in l)
        {
            var dict = new Dictionary<TSecondKey, TValue>();
            retVal.Add(item.Key, dict);
            var subdict = item.ToLookup(secondKeySelector);
            foreach (var subitem in subdict)
            {
                dict.Add(subitem.Key, aggregate(subitem));
            }
        }
        return retVal;
    }

希望得到这个帮助。