web-dev-qa-db-de.com

Foreach in einem Foreach in der MVC-Ansicht

BIG EDIT: Ich habe meinen ganzen Beitrag mit der Antwort editiert, dass ich mit Hilfe von Von V und Johannes aufgetaucht bin.

Ich habe versucht, eine foreach-Schleife innerhalb einer foreach-Schleife in meiner Indexansicht auszuführen, um meine Produkte in einem Akkordeon anzuzeigen. Lassen Sie mich Ihnen zeigen, wie ich das versuche.

Hier sind meine Modelle:

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; }
}

Es ist ein eins eins Eins-Viele-Beziehung, Ein Produkt hat nur eine Kategorie, aber eine Kategorie hatte viele Produkte.

Ich versuche aus meiner Sicht zu tun:

@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>

Ich bin mir nicht ganz sicher, ob dies der richtige Weg ist, aber ich versuche es so ziemlich. Platzieren Sie für jede Kategorie alle Produkte dieser Kategorien in einem Akkordeon-Tab.

  • kategorie 1
    • produkt 1
    • produkt 3
  • kategorie 2
    • produkt 2
    • produkt 4
  • kategorie 3
    • produkt 5

Hier werde ich mein Mapping für hinzufügen mein eins Eins-viele (Dank an Brian P) Beziehung:

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>();
    }
}

Ich werde auch meinen Controller hinzufügen, damit Sie sehen können, wie ich es gemacht habe:

public ActionResult Index()
    {
        ViewBag.Categories = db.Category.OrderBy(c => c.Name).ToList();
        return View(db.Product.Include(c => c.Category).ToList());
    }

BIG EDIT: Ich habe meinen ganzen Beitrag mit der Antwort editiert, dass ich mit Hilfe von Von V und Johannes aufgetaucht bin.

7

Nehmen wir an, die Aktionsmethode Ihres Controllers sieht so aus:

public ActionResult AllCategories(int id = 0)
{
    return View(db.Categories.Include(p => p.Products).ToList());
}

Ändern Sie Ihre Modelle wie folgt:

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; }
}

Dann übernimmt der Controller seitdem eine Kategorie als Modell (anstelle eines Produkts):

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: Fügen Sie ToList () zur Controller-Return-Anweisung hinzu.

8

Du hast:

foreach (var category in Model.Categories)

und dann 

@foreach (var product in Model)

Basierend auf dieser Ansicht und diesem Modell scheint es, dass Model vom Typ Product ist. Wenn ja, ist die zweite foreach nicht gültig. Tatsächlich könnte der erste ungültig sein, wenn Sie eine Auflistung von Product zurückgeben. 

UPDATE: 

Sie haben Recht, ich gebe das Modell vom Typ Produkt zurück. Ich auch. verstehe, was jetzt los ist, nachdem du darauf hingewiesen hast. Wie bin Ich soll das tun, was ich dann versuche, wenn ich es nicht so machen kann?

Ich bin überrascht, dass Ihr Code kompiliert wird, als Sie sagten, dass Sie ein Modell vom Typ Product zurückgeben. So kannst du es machen:

@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>
}

Dies legt nahe, dass Sie anstelle einer Product eine Sammlung von Categorymit Products zurückgeben. So etwas in 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)
2
von v.

Versuche dies:

Es sieht so aus, als würden Sie jedes Mal für jedes Produkt eine Schleife ausführen. Jetzt wird für jedes Produkt eine Schleife ausgeführt, die die gleiche Kategorie-ID wie die aktuelle Kategorie aufweist, die gerade wiederholt wird

<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>
    }
}  

1
CR41G14

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);
    }


Aussicht

Sie müssen das Modell mit der angegebenen Kategorie filtern

wie: => Model.where (p => p.CategoryID == category.CategoryID)

versuche dies...

@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>
}  
0
Ad Kahn