Skip to main content

Overview

The Category Management module provides CRUD operations for organizing products into categories. Categories help structure the product catalog and enable filtering and navigation.

Category Model

The Category model (Models/Category.cs:5-11) defines the structure for product categories:
public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string? Description { get; set; }
    public ICollection<Product>? Products { get; set; } = default!;
}

Properties

PropertyTypeRequiredDescription
IdintYesUnique identifier
NamestringYesCategory name
Descriptionstring?NoOptional category description
ProductsICollection<Product>?NoCollection of products in this category
The Products collection is a navigation property that establishes a one-to-many relationship with the Product model.

CRUD Operations

1

List Categories

View all categories in the system
2

Create Category

Add new categories to organize products
3

Edit Category

Update category name or description
4

Delete Category

Remove categories from the system

Listing Categories

The Index page (Pages/Categories/Index.cshtml.cs:22-28) retrieves all categories:
public IList<Category> Categories { get; set; } = default!;

public async Task OnGetAsync() 
{
    if (_context.Categories != null) 
    {
        Categories = await _context.Categories.ToListAsync();
    }
}
The page model exposes a Categories property that contains all categories from the database. Entity Framework Core’s ToListAsync() efficiently loads the data asynchronously.

Creating Categories

Categories can be created through the /Pages/Categories/Create.cshtml page, following the standard pattern:
public IActionResult OnGet()
{
    return Page();
}
Displays the category creation form.

Product Relationship

Categories maintain a one-to-many relationship with products:
public ICollection<Product>? Products { get; set; } = default!;

Relationship Benefits

Product Organization

Group related products together for easier management

Navigation

Enable filtering and browsing products by category

Data Integrity

Foreign key relationship ensures valid product-category associations

Cascade Operations

Handle dependent product records when modifying categories
Deleting a category that contains products may fail due to foreign key constraints. Consider implementing cascade delete or preventing deletion of categories with products.

Authorization

All category management operations require authentication:
[Authorize]
public class IndexModel : PageModel
{
    // Implementation
}
Only authenticated users can create, edit, or delete categories.

Database Context

Categories are managed through the SupermarketContext (Data/SupermarketContext.cs:14):
public DbSet<Category> Categories { get; set; }

Page Structure

The category management module follows the standard CRUD structure:
PageRoutePurpose
Index/Pages/Categories/Index.cshtmlList all categories
Create/Pages/Categories/Create.cshtmlAdd new category
Edit/Pages/Categories/Edit.cshtmlModify existing category
Delete/Pages/Categories/Delete.cshtmlRemove category

Implementation Pattern

All category pages follow a consistent pattern:
private readonly SupermarketContext _context;

public IndexModel(SupermarketContext context) 
{
    _context = context;
}
The SupermarketContext is injected for database access.
[BindProperty]
public Category Category { get; set; } = default!;
The [BindProperty] attribute enables automatic form data binding.
await _context.Categories.ToListAsync();
await _context.SaveChangesAsync();
All database operations are asynchronous for optimal performance.
To load categories with their products, use Entity Framework’s Include method:
var categoriesWithProducts = await _context.Categories
    .Include(c => c.Products)
    .ToListAsync();
This eagerly loads the product collection for each category, avoiding the N+1 query problem.
The Include method should only be used when you actually need the related products. For the category list page, loading products for every category may be unnecessary and impact performance.

Validation

Consider adding validation attributes to ensure data quality:
public class Category
{
    public int Id { get; set; }
    
    [Required]
    [StringLength(100)]
    public string Name { get; set; }
    
    [StringLength(500)]
    public string? Description { get; set; }
    
    public ICollection<Product>? Products { get; set; } = default!;
}

Best Practices

Unique Names

Ensure category names are unique to avoid confusion

Soft Delete

Consider soft deletes instead of hard deletes to preserve history

Hierarchical Categories

For complex catalogs, implement parent-child category relationships

Category Counts

Display product counts per category for better insights

Common Queries

Categories with Product Count

var categoriesWithCount = await _context.Categories
    .Select(c => new 
    {
        Category = c,
        ProductCount = c.Products != null ? c.Products.Count : 0
    })
    .ToListAsync();

Finding Empty Categories

var emptyCategories = await _context.Categories
    .Where(c => c.Products == null || c.Products.Count == 0)
    .ToListAsync();
var popularCategories = await _context.Categories
    .OrderByDescending(c => c.Products != null ? c.Products.Count : 0)
    .Take(10)
    .ToListAsync();

Build docs developers (and LLMs) love