C# MVC 视图中的 Foreach 中的 Foreach
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15973434/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Foreach in a Foreach in MVC View
提问by Guillaume Longtin
BIG EDIT : I have edited my full post with the answer that I came up with the help of Von V and Johannes, A BIG THANK YOU GUYS !!!!
大编辑:我已经编辑了我的完整帖子,答案是我在 Von V 和 Johannes 的帮助下提出的,非常感谢你们!!!!
I've been trying to do a foreach loop inside a foreach loop in my index view to display my products in an accordion. Let me show you how I'm trying to do this.
我一直在尝试在索引视图中的 foreach 循环内执行 foreach 循环,以在手风琴中显示我的产品。让我告诉你我是如何尝试做到这一点的。
Here are my models :
这是我的模型:
public class Product
{
[Key]
public int ID { get; set; }
public int CategoryID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Path { get; set; }
public virtual Category Category { get; set; }
}
public class Category
{
[Key]
public int CategoryID { get; set; }
public string Name { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
It's a one-oneone-many relationship, One product has only one category but a category had many products.
这是一对一的关系,一个产品只有一个类别,而一个类别有很多产品。
Here is what I'm trying to do in my view :
在我看来,这是我正在尝试做的事情:
@model IEnumerable<MyPersonalProject.Models.Product>
<div id="accordion1" style="text-align:justify">
@foreach (var category in ViewBag.Categories)
{
<h3><u>@category.Name</u></h3>
<div>
@foreach (var product in Model)
{
if (product.CategoryID == category.CategoryID)
{
<table cellpadding="5" cellspacing"5" style="border:1px solid black; width:100%;background-color:White;">
<thead>
<tr>
<th style="background-color:black; color:white;">
@product.Title
@if (System.Web.Security.UrlAuthorizationModule.CheckUrlAccessForPrincipal("/admin", User, "GET"))
{
@Html.Raw(" - ")
@Html.ActionLink("Edit", "Edit", new { id = product.ID }, new { style = "background-color:black; color:white !important;" })
}
</th>
</tr>
</thead>
<tbody>
<tr>
<td style="background-color:White;">
@product.Description
</td>
</tr>
</tbody>
</table>
}
}
</div>
}
</div>
I'm not quite sure this is the right way of doing it but this is pretty much what I'm trying to do. Foreach categories, put all products of that categories inside an accordion tab.
我不太确定这是正确的做法,但这几乎是我想要做的。Foreach 类别,将该类别的所有产品放在一个手风琴选项卡中。
- category 1
- product 1
- product 3
- category 2
- product 2
- product 4
- category 3
- product 5
- 类别 1
- 产品 1
- 产品 3
- 类别 2
- 产品2
- 产品 4
- 类别 3
- 产品 5
Here I will add my mapping for my one-oneone-many (Thanks Brian P) relationship :
在这里,我将为我的一对一(感谢 Brian P)关系添加映射:
public class MyPersonalProjectContext : DbContext
{
public DbSet<Product> Product { get; set; }
public DbSet<Category> Category { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Product>();
modelBuilder.Entity<Category>();
}
}
I will also add my controller so you can see how I did it :
我还将添加我的控制器,以便您可以看到我是如何做到的:
public ActionResult Index()
{
ViewBag.Categories = db.Category.OrderBy(c => c.Name).ToList();
return View(db.Product.Include(c => c.Category).ToList());
}
BIG EDIT : I have edited my full post with the answer that I came up with the help of Von V and Johannes, A BIG THANK YOU GUYS !!!!
大编辑:我已经编辑了我的完整帖子,答案是我在 Von V 和 Johannes 的帮助下提出的,非常感谢你们!!!!
采纳答案by Johannes Setiabudi
Assuming your controller's action method is something like this:
假设您的控制器的操作方法是这样的:
public ActionResult AllCategories(int id = 0)
{
return View(db.Categories.Include(p => p.Products).ToList());
}
Modify your models to be something like this:
将您的模型修改为如下所示:
public class Product
{
[Key]
public int ID { get; set; }
public int CategoryID { get; set; }
//new code
public virtual Category Category { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Path { get; set; }
//remove code below
//public virtual ICollection<Category> Categories { get; set; }
}
public class Category
{
[Key]
public int CategoryID { get; set; }
public string Name { get; set; }
//new code
public virtual ICollection<Product> Products{ get; set; }
}
Then your since now the controller takes in a Category as Model (instead of a Product):
然后你现在控制器接受一个类别作为模型(而不是产品):
foreach (var category in Model)
{
<h3><u>@category.Name</u></h3>
<div>
<ul>
@foreach (var product in Model.Products)
{
// cut for brevity, need to add back more code from original
<li>@product.Title</li>
}
</ul>
</div>
}
UPDATED: Add ToList() to the controller return statement.
更新:将 ToList() 添加到控制器返回语句。
回答by CR41G14
Try this:
尝试这个:
It looks like you are looping for every product each time, now this is looping for each product that has the same category ID as the current category being looped
看起来您每次都在为每个产品循环,现在这是为每个与当前循环的类别具有相同类别 ID 的产品循环
<div id="accordion1" style="text-align:justify">
@using (Html.BeginForm())
{
foreach (var category in Model.Categories)
{
<h3><u>@category.Name</u></h3>
<div>
<ul>
@foreach (var product in Model.Product.Where(m=> m.CategoryID= category.CategoryID)
{
<li>
@product.Title
@if (System.Web.Security.UrlAuthorizationModule.CheckUrlAccessForPrincipal("/admin", User, "GET"))
{
@Html.Raw(" - ")
@Html.ActionLink("Edit", "Edit", new { id = product.ID })
}
<ul>
<li>
@product.Description
</li>
</ul>
</li>
}
</ul>
</div>
}
}
回答by von v.
You have:
你有:
foreach (var category in Model.Categories)
and then
进而
@foreach (var product in Model)
Based on that view and model it seems that Model
is of type Product
if yes then the second foreach
is not valid. Actually the first one could be the one that is invalid if you return a collection of Product
.
在此基础上视图和模型似乎Model
是一个类型的Product
,如果是,那么第二个foreach
是无效的。实际上,如果您返回Product
.
UPDATE:
更新:
You are right, I am returning the model of type Product. Also, I do understand what is wrong now that you've pointed it out. How am I supposed to do what I'm trying to do then if I can't do it this way?
你是对的,我正在返回 Product 类型的模型。另外,既然您已经指出了问题,我确实明白出了什么问题。如果我不能这样做,我该怎么做呢?
I'm surprised your code compiles when you said you are returning a model of Product
type. Here's how you can do it:
当你说你返回一个Product
类型的模型时,我很惊讶你的代码编译。您可以这样做:
@foreach (var category in Model)
{
<h3><u>@category.Name</u></h3>
<div>
<ul>
@foreach (var product in category.Products)
{
<li>
put the rest of your code
</li>
}
</ul>
</div>
}
That suggest that instead of returning a Product
, you return a collection of Category
with Products. Something like this in EF:
这表明Product
您返回一个Category
with Products集合而不是返回 a 。在 EF 中是这样的:
// I am typing it here directly
// so I'm not sure if this is the correct syntax.
// I assume you know how to do this,
// anyway this should give you an idea.
context.Categories.Include(o=>o.Product)
回答by Ad Kahn
Controller
控制器
public ActionResult Index()
{
//you don't need to include the category bc it does it by itself
//var model = db.Product.Include(c => c.Category).ToList()
ViewBag.Categories = db.Category.OrderBy(c => c.Name).ToList();
var model = db.Product.ToList()
return View(model);
}
View
you need to filter the model with the given category
查看
您需要使用给定类别过滤模型
like :=> Model.where(p=>p.CategoryID == category.CategoryID)
像 :=> Model.where(p=>p.CategoryID == category.CategoryID)
try this...
尝试这个...
@foreach (var category in ViewBag.Categories)
{
<h3><u>@category.Name</u></h3>
<div>
@foreach (var product in Model.where(p=>p.CategoryID == category.CategoryID))
{
<table cellpadding="5" cellspacing"5" style="border:1px solid black; width:100%;background-color:White;">
<thead>
<tr>
<th style="background-color:black; color:white;">
@product.Title
@if (System.Web.Security.UrlAuthorizationModule.CheckUrlAccessForPrincipal("/admin", User, "GET"))
{
@Html.Raw(" - ")
@Html.ActionLink("Edit", "Edit", new { id = product.ID }, new { style = "background-color:black; color:white !important;" })
}
</th>
</tr>
</thead>
<tbody>
<tr>
<td style="background-color:White;">
@product.Description
</td>
</tr>
</tbody>
</table>
}
</div>
}