I have my Regions Index here that passes the regionID
for a region through as an asp-route-id
that is meant to go to this URL when the link is clicked (which it does):
/Countries/Index/{id?}
@model IEnumerable<Assig1.Models.Region>
@{
ViewData["Title"] = "Index";
}
<h1 class="alert-secondary p-2 text-center mb-3">Regions</h1>
<div class="row justify-content-start mt-2">
<div class="card mx-auto col-lg-6 mb-4 text-center" style="width: 18rem;">
<div class="card-body">
<img src="https://geology.com/world/world-map.gif" class="card-img-top" alt="Map of the World">
<h5 class="card-title text-center" style="position: relative; top: 15px;">All Regions</h5>
<br>
<a class="btn btn-success" asp-controller="Countries" asp-action="Index">Search</a>
</div>
</div>
@foreach (var item in Model)
{
<div class="card mx-auto col-lg-6 mb-4 text-center" style="width: 18rem;">
<img src="@Html.DisplayFor(modelItem => item.ImageUrl)" class="card-img-top" alt="@Html.DisplayFor(modelItem => item.RegionName)">
<div class="card-body">
<h5 class="card-title text-center">@Html.DisplayFor(modelItem => item.RegionName)</h5>
<br>
<a class="btn btn-success" asp-controller="Countries" asp-action="Index" asp-route-id="@item.RegionId">Search</a>
</div>
</div>
}
</div>
The Regions Model:
namespace Assig1.Models
{
public partial class Region
{
public Region()
{
Countries = new HashSet<Country>();
}
public int RegionId { get; set; }
public string RegionName { get; set; } = null!;
public string? ImageUrl { get; set; }
public virtual ICollection<Country> Countries { get; set; }
}
}
And on the Countries Index Page, the page will change its behaviour if a region has been selected from the previous page.
Regardless of which mode, the countries listed will be in alphabetical order.
The Countries Index Page View:
@model Assig1.ViewModel.CountriesViewModel
@{
ViewData["Title"] = "Index";
}
<h1 class="alert-secondary p-2 text-center mb-3">Countries</h1>
<p>
<a class="btn btn-primary" asp-controller="Regions" asp-action="Index">Back to Regions</a>
</p>
<div class="row justify-content-start mt-2">
@foreach (var item in Model.CountryList) {
<div class="card mx-auto col-lg-6 mb-4" style="width: 18rem;">
<img src="@Html.DisplayFor(modelItem => item.ImageUrl)" class="card-img-top" alt="@Html.DisplayFor(modelItem => item.CountryName)>
<div class="card-body">
<br>
<h5 class="card-title text-center">@Html.DisplayFor(modelItem => item.CountryName)</h5>
<br>
<a class="btn btn-primary" asp-controller="Countries" asp-action="Detail" asp-route-countryID="@item.CountryId">Details</a>
<a class="btn btn-success" asp-controller="Cities" asp-action="Index" asp-route-countryID="@item.CountryId">Cities</a>
</div>
}
</div>
</div>
My CountriesViewModel:
namespace Assig1.ViewModel
{
public class CountriesViewModel
{
public int? CountryId { get; set; }
public String CountryName { get; set; }
public String ImageUrl { get; set; }
public String RegionName { get; set; }
public int RegionId { get; set; }
public List<Models.Country> CountryList { get; set; }
}
}
The Country Model:
namespace Assig1.Models
{
public partial class Country
{
public Country()
{
Cities = new HashSet<City>();
CountryEmissions = new HashSet<CountryEmission>();
TemperatureData = new HashSet<TemperatureData>();
}
public int CountryId { get; set; }
public string? Iso3 { get; set; }
public string CountryName { get; set; } = null!;
public int? RegionId { get; set; }
public string? ImageUrl { get; set; }
public virtual Region? Region { get; set; }
public virtual ICollection<City> Cities { get; set; }
public virtual ICollection<CountryEmission> CountryEmissions { get; set; }
public virtual ICollection<TemperatureData> TemperatureData { get; set; }
}
}
I am able to list all the country records in order when there is no region id passed through, but I can't get the page to list all the countries from a specific region when there is a region id passed through.
It keeps giving me the error:
Cannot Implicitly Convert Type 'System.Linq.IQueryable<Assign1.Models.Country> to 'Microsoft.EntityFrameworkCore.Query.IIncludableQueryable<Assign1.Models.Country, Assign1.Models.Region>
When I try to explicitly convert it, the page loads but as soon as I try to pass in the region id by clicking the link in the region index, it doesn't work. It still loads every single country.
My CountriesController:
namespace Assig1.Controllers
{
public class CountriesController : Controller
{
private readonly EnvDataContext _context;
public CountriesController(EnvDataContext context)
{
_context = context;
}
// GET: Countries
public async Task<IActionResult> Index(CountriesViewModel vm, int? RegionId)
{
var envDataContext = _context.Countries.Include(c => c.Region);
if (RegionId != null)
{
envDataContext = envDataContext.Where(c => c.RegionId == RegionId);
}
vm.CountryList =
await envDataContext.ToListAsync();
return View(vm);
}
It might be due to the Region index not using a ViewModel? Or I messed up something here clearly, I don't know.
The Domain Model for reference:
Thank you!
The provided error states that this is a compilation error with this line:
var envDataContext = _context.Countries.Include(c => c.Region);
envDataContext
was declared as a Microsoft.EntityFrameworkCore.Query.IIncludableQueryable<Assign1.Models.Country, Assign1.Models.Region>
type and you are trying the value with IQueryable<Country>
in the next line.
You can resolve it by casting it to IQueryable<Country>
type during the declaration.
var envDataContext = _context.Countries.Include(c => c.Region).AsQueryable();