Search code examples
asp.net-mvcentity-frameworkdrycategoriesconventions

Displaying a list of Products sorted by Category and SubCategory in a DRY fashion


I have the following entity:

public class Product{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Category { get; set; }
    public string SubCategory { get; set; }
}

I would ultimately like to display a page that takes an IEnumerable<Product> and sorts the Products first by Category - then sorts each Category of Products by SubCategory.

What should my ViewModel look like?

At first I came up with something like this:

public class ProductListViewModel{
    public IEnumerable<Product> Products { get; set; }
    public IEnumerable<string> Categories { get; set; }
    public IEnumerable<string> SubCategories { get; set; }
}

but then my Controller becomes full of logic to extract the unique Categories and SubCategories and I have no clean way of dealing with the fact that each Category has different lists of SubCategories.

Anyone with experience in sorting objects by category - can you nudge me in the right direction of how to approach this situation cleanly? I can get the job done, but I feel I am making my code needlessly sloppy and not DRY.

I am also wondering if my Product class structured in an inappropriate way to handle Categories/SubCategories - does anyone else feel the same? (I am thinking my Categories may be better suited as separate objects entirely)


Solution

  • On your question regarding the model structure, I think that Category should definitely be a separate entity - your database will be under normalized (the Category should not be repeated multiple times in the database). Perhaps :

    public class Product{
        public int ID { get; set; }
        public string Name { get; set; }
        public Category Category { get; set; }
    }
    
    public class Category{
        public int ID { get; set; }
        public string Name { get; set; }
        public SubCategory SubCategory { get; set; }
    }
    
    
    public class SubCategory{
        public int ID { get; set; }
        public string Name { get; set; }
    }
    

    This way you can separate out the Category from the Product (you could also have several Categories for a single product by having an ICollection in the Product entity). This also creates a relationship between Category and SubCategory.