2010-09-29 132 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