Introduction to Data Modeling with Entity Framework
Entity Framework (EF) provides a flexible and powerful object-relational mapper (ORM) that simplifies data access in .NET applications. A core aspect of using EF effectively is understanding how to model your application's data.
Data modeling in EF involves defining classes that represent your database tables (or other data sources) and establishing relationships between them. EF then uses these models to interact with the database, translating your object-oriented code into database queries.
Key Concepts in EF Data Modeling
- Entities: Plain Old CLR Objects (POCOs) that represent tables in your database.
- DbContext: The primary class for interacting with the database. It represents a session with the database and can be used to query and save data.
- DbSet<TEntity>: Represents a collection of all entities in the store, or that can be queried from the store, of a given type.
- Relationships: How entities are connected (e.g., one-to-one, one-to-many, many-to-many).
Entity Classes
Entity classes are C# classes that map to tables in your database. Each property of the entity class typically maps to a column in the table.
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public int CategoryId { get; set; } // Foreign key
public virtual Category Category { get; set; } // Navigation property
public virtual ICollection<OrderDetails> OrderDetails { get; set; }
}
public class Category
{
public int CategoryId { get; set; }
public string Name { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
DbContext Configuration
The DbContext
class is central to EF. You typically derive from it and add DbSet<TEntity>
properties for each entity in your model. EF uses conventions to map these to database tables, but you can also use data annotations or the Fluent API for explicit configuration.
using Microsoft.EntityFrameworkCore;
public class ApplicationDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<OrderDetails> OrderDetails { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Fluent API configuration examples
modelBuilder.Entity<Product>()
.HasOne(p => p.Category)
.WithMany(c => c.Products)
.HasForeignKey(p => p.CategoryId);
modelBuilder.Entity<Product>()
.Property(p => p.Price)
.HasColumnType("decimal(18, 2)");
base.OnModelCreating(modelBuilder);
}
}
Relationships
EF supports mapping various relationship types:
- One-to-Many: A single category can have many products, but each product belongs to only one category. This is configured using foreign keys and navigation properties.
- Many-to-Many: For example, products can be in multiple orders, and an order can contain multiple products. This typically requires a joining table.
- One-to-One: Less common, but a single entity instance is related to exactly one other entity instance.
Example: Many-to-Many Relationship (Conceptual)
Consider products and orders. An order can have many products, and a product can be in many orders. This often involves an intermediate entity:
public class Order
{
public int OrderId { get; set; }
public DateTime OrderDate { get; set; }
public virtual ICollection<OrderDetails> OrderDetails { get; set; }
}
public class OrderDetails
{
public int OrderId { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public virtual Order Order { get; set; }
public virtual Product Product { get; set; }
}
In the DbContext.OnModelCreating
, you would configure this relationship, often defining the composite primary key for the OrderDetails
entity.
Data Modeling Strategies
- Code-First: You define your entity classes first, and EF generates the database schema. This is a very common approach.
- Database-First: You have an existing database, and EF generates entity classes and a
DbContext
from it. - Model-First: You design your model visually in a designer, and EF generates classes and database scripts.
This documentation focuses primarily on the Code-First approach, which offers the most flexibility for modern development workflows.