Entity Framework Core Models
This section delves into the core concepts of defining and managing models within Entity Framework Core (EF Core). EF Core uses Plain Old CLR Objects (POCOs) to represent your application's data entities, and a DbContext
to represent a session with the database, allowing you to query and save data.
Understanding Models
In EF Core, your models are simply C# classes that represent tables in your database. These classes define the structure of your data, including properties and relationships.
Key Concepts:
- Entities: C# classes that represent tables in your database.
- Properties: Members of your entity classes that map to columns in database tables.
- Relationships: How your entities relate to each other (e.g., one-to-one, one-to-many, many-to-many).
DbContext
: A class that represents a session with the database and can be used to query and save data.
Defining Entity Classes
You can define your entity classes by creating simple POCOs. EF Core will convention-ally infer mappings based on your class and property names. For example:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public virtual ICollection<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; }
}
Configuring Models
While conventions often suffice, you can explicitly configure your model using Data Annotations or the Fluent API. The Fluent API offers more control and is generally preferred for complex configurations.
Using Data Annotations:
Attributes like [Key]
, [Required]
, and [MaxLength]
can be used to configure your entities directly on the classes.
using System.ComponentModel.DataAnnotations;
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:
Configure your model within the OnModelCreating
method of your DbContext
.
using Microsoft.EntityFrameworkCore;
public class ApplicationDbContext : DbContext
{
public DbSet<Category> Categories { get; set; }
public DbSet<Product> Products { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Category>()
.HasMany(c => c.Products)
.WithOne(p => p.Category)
.HasForeignKey(p => p.CategoryId);
modelBuilder.Entity<Product>(entity =>
{
entity.Property(e => e.Name).IsRequired().HasMaxLength(100);
entity.Property(e => e.Price).HasColumnType("decimal(18, 2)");
});
}
}
Relationships
EF Core supports common relational mapping scenarios. Defining navigation properties in your entities and using the Fluent API or Data Annotations helps EF Core understand these relationships.
One-to-Many Relationship:
As shown in the Blog
and Post
example, a Blog
can have many Post
s, and a Post
belongs to one Blog
. This is represented by a collection navigation property in the "one" side and a single navigation property in the "many" side, along with the foreign key property.
Many-to-Many Relationship:
Many-to-many relationships are typically implemented using a join table. EF Core can automatically handle this if you configure it correctly.
Table and Column Mapping
By convention, EF Core maps entity class names to table names and property names to column names. You can customize this mapping:
- Table Mapping: Use
.ToTable("TableName")
in the Fluent API. - Column Mapping: Use
.HasColumnName("ColumnName")
in the Fluent API or[Column("ColumnName")]
Data Annotation.
Primary Keys
EF Core follows conventions for identifying primary keys:
- A property named
Id
orClassNameId
. - A property decorated with
[Key]
.
Further Reading
Explore the official Microsoft documentation for more in-depth details on model configuration, advanced relationships, and performance considerations.