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();
Login to leave a comment.