Learn

LINQ can take advantage of navigational properties coded into the entity models. This is a C# way of supporting one to many and many to many data relationships.

We start by adding lines to our models so that Entity Framework knows that the two tables are related. Continents have a collection of Countries:

public ICollection<Country> Countries { get; set; }

And Countries have a related Continent:

public Continent Continent { get; set; }

We can enhance our Continent Detail page by including a list of related Countries. The LINQ record retrieval statement for a single Continent can add the Include() chain statement. EF loads all related Countries each time it loads a Continent. The AsNoTracking() is a hint that says we will not be updating the Countries. This improves performance:

Continent = await _context.Continents .Include(c => c.Countries) .AsNoTracking() .FirstOrDefaultAsync(m => m.ID == id);

Markup is then added to the page to display the list of member Countries. This can easily be copied from the Countries Index page made earlier.

Instructions

1.

Open the file Models/Continent.cs. Add a using statement for collections:

  • System.Collections.Generic
2.

Add a public collection of Countries to the Continent model. This is called a navigation property in EF.

3.

Open the file Models/Country.cs. While we are on this topic, add a relation to the parent Continent.

This provides access to the related Continent when we retrieve a Country.

4.

Open the file Pages/Continents/Detail.cshtml.cs. Modify the record retrieval statement so that it uses the Include() chain statement. EF loads all related countries each time it loads a Continent. The AsNoTracking() is an EF hint that says we will not be updating the countries. This improves performance.

5.

Open the file Pages/Continents/Detail.cshtml. Add a section below all markup for the countries header. It has to use the model to get the proper column display headings. The basic format can be copied from Pages/Countries/Index.cshtml. The syntax is a bit tricky since we are dealing with a List of Continents inside a Country. The provided syntax gets the first row of that List:

<div class="d-flex bg-success text-white mt-3"> <div class="p-2" style="flex:0 0 10%"> @Html.DisplayNameFor(model => model.Continent.Countries.FirstOrDefault().ID) </div> <div class="p-2" style="flex:0 0 10%"> @Html.DisplayNameFor(model => model.Continent.Countries.FirstOrDefault().ContinentID) </div> <div class="p-2" style="flex:0 0 20%"> @Html.DisplayNameFor(model => model.Continent.Countries.FirstOrDefault().Name) </div> <div class="p-2" style="flex:0 0 15%"> @Html.DisplayNameFor(model => model.Continent.Countries.FirstOrDefault().Population) </div> <div class="p-2" style="flex:0 0 20%"> @Html.DisplayNameFor(model => model.Continent.Countries.FirstOrDefault().UnitedNationsDate) </div> <div class="p-2" style="flex:0 0 25%">Options</div> </div>
6.

Then add a loop to show each row. The basic format can again be copied from Pages/Countries/Index.cshtml. Even the buttons can be made to work if you modify the asp-page helper:

@foreach (var item in Model.Continent.Countries) { <div class="d-flex border-left border-right border-bottom border-success"> <div class="p-2" style="flex:0 0 10%"> @Html.DisplayFor(modelItem => item.ID) </div> <div class="p-2" style="flex:0 0 10%"> @Html.DisplayFor(modelItem => item.ContinentID) </div> <div class="p-2" style="flex:0 0 20%"> @Html.DisplayFor(modelItem => item.Name) </div> <div class="p-2" style="flex:0 0 15%"> @Html.DisplayFor(modelItem => item.Population) </div> <div class="p-2" style="flex:0 0 20%"> @Html.DisplayFor(modelItem => item.UnitedNationsDate) </div> <div class="p-2 btn-group" style="flex:0 0 25%" role="group" > <a class="btn btn-primary btn-sm" asp-page="/Countries/Detail" asp-route-id="@item.ID">Details</a> <a class="btn btn-primary btn-sm" asp-page="/Countries/Edit" asp-route-id="@item.ID">Edit</a> <a class="btn btn-danger btn-sm" asp-page="/Countries/Delete" asp-route-id="@item.ID">Delete</a> </div> </div> }

Run the site and view the results in the browser. Select the Continent list and click on the Details button for a Continent. Related Country records should display. Try the option buttons for the member countries

Sign up to start coding

By signing up for Codecademy, you agree to Codecademy's Terms of Service & Privacy Policy.
Already have an account?