线或整 w=10=sh

Linq or Tsql 'Pivot'

我确定这在其他地方已经涵盖,但我在为此找到一个优雅的解决方案时遇到了一些问题。

ID  C     D
1   Apple Red
1   Pear  Orange
2   Apple Red 
2   Pear  Orange

我想要结束的是:

ID  | Benefit | Value
1   | C       | Apple
1   | C       | Pear
2   | C       | Apple
2   | C       | Pear
1   | D       | Red
1   | D       | Orange
2   | D       | Red
2   | D       | Orange

我可以在 Linq 中通过扫描每一列并添加到列表中来完成。

public class SampleRow
{
    public Int32 Id { get; set; }
    public String A { get; set; }
    public String B { get; set; }        
}

public class SampleOutput
{
    public Int32 Id { get; set; }
    public String Description { get; set; }
    public String Value { get; set; }  

}

        List<SampleRow> rows = new List<SampleRow>();
        rows.Add(new SampleRow
        {
            Id = 1,
            A = "Apple",
            B = "Red"
        });
        rows.Add(new SampleRow
        {
            Id = 1,
            A = "Pear",
            B = "Orange"
        });
        rows.Add(new SampleRow
        {
            Id = 2,
            A = "Apple",
            B = "Red"
        });
        rows.Add(new SampleRow
        {
            Id = 2,
            A = "Pear",
            B = "Orange"
        });


        List<SampleOutput> output = new List<SampleOutput>();
        rows.ForEach(row =>
            output.Add(new SampleOutput()
            {
                Id = row.Id,
                Description = "A",
                Value = row.A
            })
            );
        rows.ForEach(row =>
            output.Add(new SampleOutput()
            {
                Id = row.Id,
                Description = "B",
                Value = row.B
            })
            );

我想知道是否有更好的方法。我对 Linq 或 TSQL 解决方案持开放态度。数据存储在 SQL 中,就像第一个 table/object 列表一样。

我认为一个干净优雅的解决方案是使用 UNPIVOT。

SELECT
  ID, Benefit, Value
FROM
  Test
UNPIVOT
  (Value FOR Benefit IN (C, D)) unpvt
ORDER BY
  Benefit, ID

这里有一个工作演示
http://sqlfiddle.com/#!6/12884/9

希望对您有所帮助

通过使用 Linq,您可以更简单的方式实现:

var qry = rows.Select(c=>new{ID = c.ID, Benefit="C", Value=c.C})
        .Concat(rows.Select(d=>new{ID = d.ID, Benefit="D", Value=d.D}));

使用CopyToDataTable() method.

可以将结果集"converted"放入数据表中

[EDIT]Union 已被 Concat 取代 - 正如评论中建议的 danihp[/EDIT]