我的数据库中有两个2个表
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>
哪个输出
-------------------
|1 |apple |100|
-------------------
|1 |orange |110|
-------------------
|2 |apple |200|
-------------------
|2 |orange | 40|
-------------------
我真正看到的输出结果如下。
-------------------------
| | 1 | 2 |
-------------------------
|apple |100 |200 |
-------------------------
|orange |200 | 40 |
-------------------------
有人可以指出我正确的方向吗?
答案 0 :(得分:4)
也许存在更优雅的解决方案,但这就是我将如何做到的。
您需要一个循环来生成Foo.Number
标题行,然后您需要第二个循环,您可以选择所有Bar
并按Name
对它们进行分组。您可以从这些组中生成数据行。
现在你只需要一个遍历Bar.Value
的thrid循环并构建表格行。
所以代码中的上述“算法”:
<table>
<tr>
<td>
</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
标题正确对齐。
结果如下:
答案 1 :(得分:0)
这是一种可能的方法......我正在努力想出一个使用标准ActionResult的解决方案(虽然我确定它是可能的)所以我认为返回一个扁平的匿名json对象可能会成功。在Controller上粘贴一个JsonResult方法,通过jQuery调用它然后构建你的表。此解决方案取决于按Bar.Name排序的记录(提前警告一些未经测试的代码!)
编辑:我刚刚意识到这不太正确,需要重构。当有相同数量的Bar itms时它可以工作,但实际上每个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;
}