大きな編集:私は、Von VとJohannesの助けを借りて思いついた答えで投稿全体を編集しました。
インデックスビューでforeachループ内でforeachループを実行して、製品をアコーディオンで表示しようとしています。私がこれをどのようにしようとしているかをお見せしましょう。
ここに私のモデルがあります:
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; }
}
それは 一対一 1対多の関係。1つの製品には1つのカテゴリしかありませんが、1つのカテゴリには多くの製品がありました。
これが私の見解でやろうとしていることです:
@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>
これが正しい方法かどうかはよくわかりませんが、これは私がやろうとしていることです。カテゴリごとに、そのカテゴリのすべての製品をアコーディオンタブに入れます。
ここで、マッピングを追加します 私のワンワン 1対多(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>();
}
}
また、コントローラーを追加して、どのように実行したかを確認できるようにします。
public ActionResult Index()
{
ViewBag.Categories = db.Category.OrderBy(c => c.Name).ToList();
return View(db.Product.Include(c => c.Category).ToList());
}
大きな編集:私は、Von VとJohannesの助けを借りて思いついた答えで投稿全体を編集しました。
コントローラーのアクションメソッドが次のようなものであると仮定します。
public ActionResult AllCategories(int id = 0)
{
return View(db.Categories.Include(p => p.Products).ToList());
}
モデルを次のように変更します。
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; }
}
その後、コントローラは(製品ではなく)モデルとしてカテゴリを取得します:
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>
}
更新:ToList()をコントローラーのreturnステートメントに追加します。
あなたが持っている:
foreach (var category in Model.Categories)
その後
@foreach (var product in Model)
そのビューとモデルに基づいて、Model
はProduct
型であると思われます。yesの場合、2番目のforeach
は無効です。実際、Product
のコレクションを返す場合、最初のものは無効なものである可能性があります。
更新:
あなたは正しい、タイプProductのモデルを返しています。また、あなたが指摘した今、何が間違っているのか理解しています。このようにできない場合、どうすれば自分がやろうとしていることをするのですか?
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>
}
つまり、Product
を返す代わりに、Category
with Productsのコレクションを返すことをお勧めします。 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)
これを試して:
毎回すべての製品をループしているように見えますが、現在、これはループされている現在のカテゴリーと同じカテゴリー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>
}
}
コントローラー
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);
}
表示
指定されたカテゴリでモデルをフィルタリングする必要があります
like:=> Model.where(p => p.CategoryID == category.CategoryID)
これを試して...
@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>
}