Modeling Data with EF Core

Learn how to define and manage your application's data using Entity Framework Core.

Introduction to Data Modeling with EF Core

Entity Framework Core (EF Core) is a modern, cross-platform, open-source version of the popular Entity Framework data access technology. EF Core makes it easier for .NET developers to work with databases by providing an object-relational mapper (ORM). This guide focuses on how to define your domain model and configure EF Core to map it to your database schema.

Defining Your Domain Model

Your domain model consists of your application's core entities and their relationships. In EF Core, these are typically represented by Plain Old CLR Objects (POCOs).

Entity Classes

An entity class represents a table in your database. Properties of the entity class map to columns in the table. EF Core conventions automatically infer much of this mapping, but you can customize it using Data Annotations or the Fluent API.

Example: A Simple Blog Entity

public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public int BlogId { get; set; } public Blog Blog { get; set; } }

Relationships

EF Core supports various relationships, including one-to-one, one-to-many, and many-to-many. These are defined by including navigation properties in your entity classes.

  • One-to-Many: A Blog can have many Posts. This is shown in the example above with Blog.Posts and Post.Blog.
  • Many-to-Many: Requires a joining table, often configured using the Fluent API.

Configuring the Model

EF Core provides two primary ways to configure your model:

  • Data Annotations: Attributes placed directly on your entity classes (e.g., [Key], [Required], [MaxLength]).
  • Fluent API: Configured in the OnModelCreating method of your DbContext. This offers more control and is generally preferred for complex configurations.

Using Data Annotations

Data Annotations are attributes from the System.ComponentModel.DataAnnotations namespace.

Example: Using Data Annotations

using System.ComponentModel.DataAnnotations; using System.Collections.Generic; public class Product { [Key] public int ProductId { get; set; } [Required] [MaxLength(100)] public string Name { get; set; } public decimal Price { get; set; } }

Using the Fluent API

The Fluent API is configured within the DbContext.OnModelCreating method.

Example: Using the Fluent API

using Microsoft.EntityFrameworkCore; public class MyDbContext : DbContext { public DbSet<Category> Categories { get; set; } public DbSet<Item> Items { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Category>() .ToTable("ProductCategories") .HasKey(c => c.CategoryId); modelBuilder.Entity<Category>() .Property(c => c.Name) .IsRequired() .HasMaxLength(50); modelBuilder.Entity<Item>() .HasOne(i => i.Category) .WithMany(c => c.Items) .HasForeignKey(i => i.CategoryId); } } public class Category { public int CategoryId { get; set; } public string Name { get; set; } public ICollection<Item> Items { get; set; } } public class Item { public int ItemId { get; set; } public string Description { get; set; } public int CategoryId { get; set; } public Category Category { get; set; } }

Advanced Modeling Concepts

  • Owned Types: For entities that don't have their own identity and are only part of another entity.
  • Value Objects: Immutable types representing a descriptive aspect of the domain.
  • Table Splitting: Mapping multiple entity types to a single database table.
  • TPH (Table-Per-Hierarchy): Mapping a hierarchy of entity types to a single table.
  • TPC (Table-Per-Concrete Type): Mapping each concrete entity type to its own table.
  • TPT (Table-Per-Type): Mapping an entity hierarchy to tables where a base table contains common properties and derived tables contain specific properties.

Explore the Advanced Modeling section for details on these concepts.