2010-09-29 137 views
2

我有一个表(如数字列表),通过一系列linq查询重新创建。我试图根据第一行中的值以降序对列进行排序。另一个LINQ OrderBy查询

我的数据库看起来是这样的:

Data 
{ 
    ColumnLabel, 
    RowLabel, 
    Value 
} 

{"Cat", "All", 9} 
{"Dog","All", 17} 
{"Fish", "All", 4} 

{"Cat", "Girls", 3} 
{"Dog","Girls", 2} 
{"Fish", "Girls", 2} 

{"Cat", "Boys", 6} 
{"Dog","Boys", 15} 
{"Fish", "Boys", 2} 

当我天真地加入这个表一起,它看起来是这样的:

 Cat | Dog | Fish 
All 9  17  4 
Girls 3  15  2 
Boys 6  2  2 

我想要做的排序是按降序根据订单ColumnLabels其中我希望桌子看起来像这样:

 Dog | Cat | Fish 
All 17 9  4 
Girls 15 3  2 
Boys 2  6  2 

注意狗和猫排翻转。

我需要把这个表格使用HTML,所以我遍历每行。

我通过排序ColumnLabels开始:

变种顶部= data.Where(X => x.RowLabel == “全部”) .OrderBy(X => x.Data) 。选择(X => x.ColumnLabel).SingleOrDefault();

现在top包含我希望列出现的顺序; {Dog, Cat, Fish}。我并不在乎行如何垂直排序。

我再想做的是基于组的每一行其所在的RowLabel值:

var row = data.GroupBy(x => x.RowLabel) 
      .OrderBy(y => ??????????????); 
      //I want to OrderBy the values in top 
      //How do I do this? 

我再通过各行进行迭代,并创建我的HTML表格。这部分很简单,但我不知道如何根据最高顺序订购后续行。我如何在LINQ中做到这一点?

回答

2

我相信这会做你想要什么:

var order = data 
    .Where(x => x.RowLabel == "All") 
    .OrderByDescending(x => x.Value) 
    .Select((x, i) => new { x, i }) 
    .ToDictionary(x => x.x.ColumnLabel, x => x.i); 
var result = data 
    .GroupBy(x => x.RowLabel, (x, y) => y.OrderBy(z => order[z.ColumnLabel])); 

foreach (var x in result) 
{ 
    foreach (var y in x) 
    { 
     Console.WriteLine("ColumnLabel: {0}, RowLabel: {1}, Value: {2}", y.ColumnLabel, y.RowLabel, y.Value);      
    } 
} 

结果:

ColumnLabel: Dog, RowLabel: All, Value: 17 
ColumnLabel: Cat, RowLabel: All, Value: 9 
ColumnLabel: Fish, RowLabel: All, Value: 4 
ColumnLabel: Dog, RowLabel: Girls, Value: 2 
ColumnLabel: Cat, RowLabel: Girls, Value: 3 
ColumnLabel: Fish, RowLabel: Girls, Value: 2 
ColumnLabel: Dog, RowLabel: Boys, Value: 15 
ColumnLabel: Cat, RowLabel: Boys, Value: 6 
ColumnLabel: Fish, RowLabel: Boys, Value: 2 

让我知道如果我误解了你的问题,但这里的想法是创建一个字典order提供后续分组查询的排序。另一个关键想法是使用group-by的resultSelector对内部元素进行排序(因为这些元素代表了列)。

+0

这看起来“正确”乍一看。让我试试看,我会稍微回应一下。 :) – Harry 2010-09-29 05:23:03

+0

如果我有多个groupBy,如何使用上面的代码。例如:.GroupBy(x => new {x.RowLabel,x.MoreRowLabel}),(x,y)...)当它到达委托时它会引发错误。 – Harry 2010-09-29 05:47:18

+0

你是什么意思由多个groupBy?什么错误? – 2010-09-29 06:15:09

1

想过这个之后,这就是我想出来的。它或多或少与Kirk's一样,但不使用字典。我正在瞄准一个单一的查询来做到这一点,(select ... into)真的救了我。

var query = from item in data 
      where item.RowLabel == "All" 
      orderby item.Value descending 
      select item.ColumnLabel into columnOrder 
      join item in data on columnOrder equals item.ColumnLabel 
      group item by item.RowLabel; 

var lquery = data.Where(item => item.RowLabel == "All") 
       .OrderByDescending(item => item.Value) 
       .Select(item => item.ColumnLabel) 
       .Join(data, columnOrder => columnOrder, 
          item => item.ColumnLabel, 
          (columnOrder, item) => item) 
       .GroupBy(item => item.RowLabel); 
+0

您最后一次...进入实际上是多余的 - 您可以结束第一个查询与“逐个项目组”。RowLabel;' – 2010-09-30 10:36:25

+0

@Pete:啊,错过了获取问题中的行的点。我以为他想要每个单独的项目。感谢您指出了这一点。 – 2010-09-30 10:46:14