EFCore+Razor Pages: nested foreach loop iterating over .included dataset returning zero results

asp.net-core-mvc c# entity-framework-6 linq razor-pages

Question

I am attempting to make a DotnetCore C# MVC Razor Page created by EF core show related table data and appear to either be having a problem with LINQ .include in my pagemodels OnGetAsync method or when trying to show the included contents in the Razor page.

Any assistance would be appreciated. Please let me know if I can provide any more relevant information. I've only been doing EFCore/RazorPages/Mvc/C# for a couple months now, so please be kind!

Here is the index.cshtml.cs page where I include childtable:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Appname.Models;

namespace Appname.Pages.Request
{
    public class IndexModel : PageModel
    {
        private readonly Appname.Models.dbContext _context;

        public IndexModel(Appname.Models.dbContext context)
        {
            _context = context;
        }

        public IList<ParentTable> ParentTable { get;set; }

        public async Task OnGetAsync()
        {
            ParentTable = await _context.ParentTable
                .Include(w => w.ChildTable)
                .ToListAsync(); //Output to an async list
            }
        }
    }
}

Here is the Index.cshtml razor page where the nested foreach loop iterating over Model.ParentTable[0].ChildTable never has its conditions satisfied because Model.ParentTable[0].ChildTable has a count of zero when inspected during debugging and therefore no data for ChildField1 or ChildField2 is displayed:

@page
@model Appname.Pages.Request.IndexModel

@{
    ViewData["Title"] = "Index";
}

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.ParentTable[0].ParentField1)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ParentTable[0].ParentField2)
            </th>  
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.ParentTable)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.ParentField1)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ParentField2)
                </td>
                <td>
                    <table class="table">
                        <tr>
                            <th>Child Field 1</th>
                            <th>Child Field 2</th>
                        </tr>
                        @foreach (var relatedItem in Model.ParentTable[0].ChildTable)
                        {
                             <tr>
                                <td>
                                    @Html.DisplayFor(modelItem => relatedItem.ChildField1)
                                </td>
                                <td>
                                    @Html.DisplayFor(modelItem => relatedItem.ChildField2)
                                </td>
                            </tr>
                        }
                    </table>
                </td>
                <td>
                    <a asp-page="./Edit" asp-route-id="@item.ParentTableid">Edit</a> |
                    <a asp-page="./Details" asp-route-id="@item.ParentTableid">Details</a>
                </td>
            </tr>
        }
    </tbody>
</table>

Here is the ParentTable model:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Appname.Models
{
    public partial class ParentTable
    {
        [Key]
        public long ParentTableid { get; set; }
        public string ParentField1 { get; set; }
        public string ParentField2 { get; set; }
        public ICollection<ChildTable> ChildTable { get; set; }
    }
}

...And the ChildTable model, using non-standard ID naming conventions for EF Core because that's how the field was designed in the database this is being written to work with long ago (not sure if this is part of the problem or if I have my key fields set up wrong):

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Appname.Models
{
    public partial class ChildTable
    {
        public long nonstandardidfield { get; set; }
        public string ChildField1 { get; set; }
        public string ChildField2 { get; set; }

        [ForeignKey("nonstandardidfield")]
        public ParentTable ParentTable { get; set; }
    }
}

Thank you for your time.

1
0
3/26/2018 6:19:01 PM

Accepted Answer

It looks to me that you are only every iterating over the ChildTable items of the first Model.

Change this:

@foreach (var relatedItem in Model.ParentTable[0].ChildTable)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => relatedItem.ChildField1)
        </td>
        <td>
            @Html.DisplayFor(modelItem => relatedItem.ChildField2)
        </td>
    </tr>
}

To:

@foreach (var relatedItem in item.ChildTable)
{
    <tr>
        <td>
            @Html.DisplayFor(ri => relatedItem.ChildField1)
        </td>
        <td>
            @Html.DisplayFor(ri => relatedItem.ChildField2)
        </td>
    </tr>
}
0
3/27/2018 5:34:02 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow