Search code examples
sql-serverasp.net-mvcasp.net-corerazor

How to get the Category Name using ID when the page is using another table


I have tables Categories and SubCategories in SQL Server. Both of them have an Id and a Name column.

The view page shows a list of subcategories that is under one of the categories.

At the top of the page, I want to show the ID and Name of the category they clicked on.

The ID is already set up at the top of the page since it is also in the controller (though I don't know where)

@{
    List<SubCategory1> subCategories1 = (List<SubCategory1>)ViewBag.subCategories;
    int id = (int)ViewBag.id;
}

So I can already display it on the page by typing <p>@id</p>.

But where do I need to add this either in the controller, entity, or page to also display the category name based on the category ID

I tired to add it to the Entity and also add the Category DB the same as the subCategories but I still don't know how to add the Category Name the same as the ID is

public virtual Category CategoryName { get; set; }

List<Category> categoryList = (List<Category>)ViewBag.categoryName;

I've looked at similar posts but they want to show the ID and Name within the list and not in the same way as my ID is set up.


Solution

  • Accepted answer says "you can inject your dbcontext into your view"

    DON'T DO THAT. NEVER.

    You are using MVC (Model - View - Controller), don't place any database call inside the view - this should be done in other layers.

    In your situation, just strongly-type your view using @model YourNamespace.CategoryViewModel

    Then, define CategoryViewModel in a model class according to your need, probably :

    public class CategoryViewModel 
    {
        public string Name { get; set; }
    
        //SubCategory is another model class with required properties
        public IList<SubCategory> subcategories { get; set; }
        
        // Other properties required by your view
    }
    

    Your controller will look like something like this

    public ActionResult Index(int id)
    {
        // Call your service class which encapsulate the logic
        var model = yourServiceClass.PopulateModel(id);
    
        // return the View with your model
        return View("path-to-your-view", model)
    }
    

    Finally, in your service class, populate your model

    public List<CategoryViewModel> PopulateModel(id)
    {
        // Populate your model via a database call using _context.yourmethod()
    }
    

    Now, your view is strongly-typed with a CategoryViewModel, which has the Category name and a list of sub-categories with their own properties ; you can now display them as you want in the view.

    Best way would be to get an intermediary layer, like getting a model from your database, then mapping it to a ViewModel, but let's keep it simple first.

    In a general way, please avoid :

    • To use a ViewBag to pass properties to your view. This should be done via a ViewModel.
    • To call your database inside the view : this is a terrible bad practice. You don't need to think twice, just don't do it :