2012-07-20 68 views
3

我有我的數據庫中有兩個2表MVC 3剃鬚刀顯示父/子表作爲一個表

Table: Foo     Table: Bar 
-----------------   --------------------- 
|FooID  | Int|   |BarID  | Int | 
|Number | Int|   |FooID  | Int | 
-----------------   |Name  | String | 
          |Value  | Int | 
          --------------------- 

With data     with data 
|FooID | Number |   |BarID |FoodID |Name |Value | 
|1  | 1  |   |1  |1  |apple |100 | 
|2  | 2  |   |2  |1  |orange |110 | 
          |3  |2  |apple |200 | 
          |4  |2  |orange |40 | 

以上是相關車型

class Foo 
{ 
    public int FooID { get; set; } 
    public int Number { get; set;} 

    public virtual ICollection<Bar> Bars { get; set; } 
} 

class Bar 
{ 
    public int BarID { get; set; } 
    public int FooID { get; set; } 
    public string Name { get; set;} 
    public int Value { get; set;} 
} 

我可以伊斯利在這樣一個表中顯示此通過在其輸出

視圖

<table> 
    @foreach(var f in Model) 
    { 
     <tr> 
      foreach(var b in f.Bar) 
      { 
       <td>@f.Number</td> 
       <td>@b.Name</td> 
       <td>@b.Value</td> 
      } 
     </tr> 
    } 
</table> 

做follwing格式

------------------- 
|1 |apple |100| 
------------------- 
|1 |orange |110| 
------------------- 
|2 |apple |200| 
------------------- 
|2 |orange | 40| 
------------------- 

我真的會看到輸出結果如下。

------------------------- 
|   | 1  | 2 | 
------------------------- 
|apple |100  |200 | 
------------------------- 
|orange |200  | 40 | 
------------------------- 

有人能指點我在正確的方向?

+0

你肯定Foo.Number將始終從1開始,sequencialy增長? – Mohayemin 2012-07-20 23:14:10

+0

感謝您的回覆。是的,我確信它將從1開始並逐步增長......但是這很重要嗎?如果Foo.Number是一個字符串而不是Int?任何建議幫助。再次感謝! – 2012-07-20 23:36:20

+0

噢,我想我知道你可能在...... Foo.Number將重置爲1並在我的應用程序中再次備份。我試圖通過刪除多餘的字段來簡化我的問題。 – 2012-07-20 23:39:20

回答

4

也許有更優雅的解決方案存在,但這裏是我會怎麼做。

您需要一個循環來生成Foo.Number中的標題行,然後您需要第二個循環,您可以在其中選擇所有Bar s並按它們的Name對它們進行分組。從這些組中可以生成數據行。

現在,您只需要一個通過Bar.Value s構建表格行的第三個循環。

所以上述的「算法」中的代碼:

<table> 
    <tr> 
     <td> 
      &nbsp; 
     </td> 
     @foreach (var f in Model.OrderBy(f => f.FooID)) 
     { 
      <td>@f.Number 
      </td> 
     } 
    </tr> 
    @foreach (var group in Model.SelectMany(f => f.Bars).GroupBy(b => b.Name)) 
    { 
     <tr> 
      <td>@group.Key 
      </td> 
      @foreach (var b in group.OrderBy(b => b.FooID)) 
      { 
       <td>@b.Value 
       </td> 
      } 
     </tr> 
    } 
</table> 

注:我已經添加了OrderBy(b => b.FooID),以確保該Bar值正確地與Foo.Number頭對齊。

而這個結果看起來像:

enter image description here

+0

**謝謝** sooo much @nemesv!你的代碼工作。它看起來有點把foo吧的情況翻譯回我的應用程序,但我把它運用起來了。再次感謝! – 2012-07-21 20:52:04

0

這裏有一種可能的方法...我正在努力想出一個使用標準ActionResult的解決方案(雖然我確信這是可能的),所以我認爲返回一個扁平化的匿名json對象可能會訣竅。在你的Controller上粘貼一個JsonResult方法,通過jQuery調用它然後建立你的表。這個解決方案取決於Bar.Name排序的記錄(警告一些未經測試的代碼!)

編輯:我剛剛意識到這並不完全正確,需要重構。它適用於Bar條數相同的情況,但實際上每個Foo可能會有一個可變數字,因此添加到每行的元素數量需要等於Bar條目的最大數量。

public JsonResult GetBarsForFoos() 
{ 
    var foos = from f in repositoryOrContext.Foos.Include("Bar") 
     select f; 

    return foos == null 
    ? Json(new object[0], JsonRequestBehavior.AllowGet) 
    : Json(foos.Bars.OrderBy(bar => bar.Name).Select(
     bar => new { foos.Number, bar.Name, bar.Value }).ToArray(), 
     JsonRequestBehavior.AllowGet); 
} 

然後在jQuery的:

function populateFoos() { 
    $.ajax({ 
     url: '/Foo/GetBarsForFoos', 
     async: false 
    }).done(function (data) { 
     // have an empty table in your Razor with an id of tblFoos 
     var fooTable = $('#tblFoos'); 
     fooTable.html(''); 
     fooTable.append(createFooTable(data)); 
    }).error(function (msg, url, line) { 
     alert("Error - error message: " + line); 
    }); 
} 

function createFooTable(data) { 
    var html = '', 
    len = data.length, 
    currentBarName = '', 
    allBarNumbers = []; 

    html = '<table><tr><td></td>'; 

    // Create 1st row that contains foo.Number 
    for (var i = 0; i < len; i++) { 

     if (allBarNumbers.indexOf(data[i].Number) === -1) { 
      allBarNumbers.push(data[i].Number); 

      html += '<td>' + data[i].Number + '</td>'; 
     }   
    } 

    html += '</tr>'; 

    // Create further rows that line up Name and Value under their foo.Number values 
    for (var x = 0; x < len; x++) { 

     if (x === 0) { 
      html += '<tr>'; 
     } 

     // grab Bar name if changed 
     if (currentBarName != data[x].Name) { 
      currentBarName = data[x].Name; 

      if (x !== 0) { 
       html += '</tr><tr>'; 
      } 
      html += '<td>' + currentBarName + '</td>'; 
     } 

     html += '<td>' + data[x].Value + '</td>'; 
    } 

    html += '</tr>/<table>'; 

    return html; 
} 

您可以使用此測試createFooTable:

function testFooTable() { 

    var data = [ 
     { Number: 1, Name: 'apple', Value: 100 }, 
     { Number: 2, Name: 'apple', Value: 200 }, 
     { Number: 1, Name: 'orange', Value: 110 }, 
     { Number: 2, Name: 'orange', Value: 40 } 
    ]; 

    var fooTable = createFooTable(data); 

    return fooTable; 
}