Understanding One-to-Many Relationships in EF Core using Dotnet core 8

nitish96
Nitish Sharma
Published on: January 12, 2025
Updated on: January 13, 2025
Understanding One-to-Many Relationships in EF Core using Dotnet core 8 blog

Entity Framework Core (EF Core) is a powerful Object-Relation Mapper (ORM) that users use to access databases in.NET applications. One of its best features is its ability to handle relationships between models, including one-to-many relationships between models, including one-to-many relationships. In this article, we will be looking at one-to-many relationships in EF Core.

What is a One-to-Many relationship?

A one-to-many relationship exists when a single model is related to multiple instances of another model.

 For example, a category can have many Products, but a product belongs to only one Category. 

Declare One-to-Many Relationships in EF Core.

In EF Core, one-to-many relationships are declared using navigation properties and foreign key constraints.

public class Category
{

    public int Id { get; set; }

    public string Name { get; set; }

    public List<Product> Products { get; set; } = new();

}


public class Product
{
    public int Id { get; set; }

    public string Name { get; set; }

    public int CategoryId { get; set; } // Foreign Key

    public Category Category { get; set; }

}

  • The Products collection in category represents the "many" side.
  • The Category property in product represents the "one" side.
  • The CategoryId property acts as the.

public class ApplicationDbContext : DbContext
{
    public DbSet<Category> Categories { get; set; }

    public DbSet<Product> Products { get; set; }
}

Common Pitfalls in One-to-Many Relationships

1. Unintended Lazy Loading

EF Core use lazy loading, which means related data is only loaded when you are accessed.

Migrations:

  • Use eager loading with .Include() to load related data in a single query.
  • Use explicit loading when you need more control over when data is loaded.
var categories = await _context.Categories
    .Include(c => c.Products)
    .ToListAsync();

2. Cascade Delete Issue

  • Unintentional cascade deletes can lead to data loss.
  • Migration:

    • Configure delete behaviour in the Fluent API.
    • Use DeletBahavior.Restrict or DeleteBehavior.SetNull as appropriate.
modelBuilder.Entity<Product>() .HasOne(p => p.Category) 
.WithMany(c => c.Products) .OnDelete(DeleteBehavior.Restrict);

3. Tracking vs No-Tracking Queries

  • Failing to differentiate between tracking and no-tracking queries can result in unexprected behaviour, such as stale data or performance issues.
  • Use .AsNoTracking for read-only queries to improve performance.
var products = context.Products.AsNoTracking().ToList();

Comments

Login to leave a comment.

Build Software Application with Impact Hive