I'm working on building a website in ASP.NET Core MVC (the latest version). I have Animals table and Categories table,looking like this:
On my AdminController I have Index action that should show eventually a table that displays the animal's data table (name, age, picture, description) and ALSO its category. It meant that I need the data from both Animals and Categories tables.
The problom is that I don't understand how to do this combination. I've tried to use ViewModel but I still don't now how to approach both animal's data and it's category for each animal?
Right now everything works fine except the Category name part - which stays empty. I think my problom is on the foreach part but I don't know how to fix it.
Here is my code- Admin Controller:
public class AdminController : Controller
{
readonly IAnimalService _animalService;
readonly ICategoryService _categoryService;
public AdminController(IAnimalService animalService, ICategoryService categoryService)
{
_animalService = animalService;
_categoryService = categoryService;
}
public async Task<IActionResult> Index()
{
var model = new AdminViewModel()
{
Animals = await _animalService.GetAllAsync(),
Categories = await _categoryService.GetAnimalCategory()
};
return View(model);
}
Admin ViewModel:
namespace PetShop.Client.Models
{
public class AdminViewModel
{
public IQueryable<Animal> Animals { get; set; }
public IQueryable<Category> Categories { get; set; }
}
}
Index View:
@model PetShop.Client.Models.AdminViewModel
@{
ViewBag.Title = "Index";
}
<h1>Index</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<table >
<thead>
<tr>
<th>
@Html.DisplayNameFor(m=> Model.Animals.FirstOrDefault().Name);
</th>
<th>
@Html.DisplayNameFor(m=> Model.Animals.FirstOrDefault().BirthDate);
</th>
<th>
@Html.DisplayNameFor(m=> Model.Animals.FirstOrDefault().Description);
</th>
<th>
@Html.DisplayNameFor(m=> Model.Animals.FirstOrDefault().PhotoUrl);
</th>
<th>
@Html.DisplayNameFor(m=> Model.Categories.FirstOrDefault().Name);
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Animals) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.BirthDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.Description)
</td>
<td>
@Html.DisplayFor(modelItem => item.PhotoUrl)
</td>
<td>
@Html.DisplayFor(modelItem => item.Category.Name)
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.AnimalId">Edit</a> |
<a asp-action="Details" asp-route-id="@item.AnimalId">Details</a> |
<a asp-action="Delete" asp-route-id="@item.AnimalId">Delete</a>
</td>
</tr>
}
</tbody>
</table>
CodePudding user response:
you have to include category in _animalService.GetAllAsync()
return await _context.Animals.Include(i=>i.Category);
and IMHO I can' t see what do you need IQueryable Categories for. And maybe you will have to change IQuerable's to IEnumerable 's too.