Entity Framework Core Models
Understanding and defining your data models is fundamental to using Entity Framework Core (EF Core) effectively. EF Core uses Plain Old CLR Objects (POCOs) to represent your database schema. These POCOs are also known as entities.
Core Concepts
In EF Core, models are built using a combination of:
- Entities: Plain C# classes that represent tables in your database. Each property in an entity typically maps to a column in the table.
- DbContext: A session-like object that encapsulates a connection to your database and allows you to query and save data. It's the primary way to interact with EF Core.
- DbSet: A property on your
DbContext
that represents a collection of all entities in the given entity type, or that can be queried from the database.
Defining Your Entities
You can define your entities simply by creating C# classes. EF Core can infer a lot about your model convention-based, but you can also use data annotations or the Fluent API to configure your model in detail.
Example: A Simple Blog Post Entity
namespace YourAppName.Models
{
public class Post
{
public int Id { get; set; } // Primary Key (conventionally inferred)
public string Title { get; set; }
public string Content { get; set; }
public DateTime PublishedDate { get; set; }
// Navigation property to the author
public int AuthorId { get; set; }
public Author Author { get; set; }
}
public class Author
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
// Navigation property to the posts
public ICollection<Post> Posts { get; set; }
}
}
Configuring Your Model
Data Annotations
You can use attributes from the System.ComponentModel.DataAnnotations
namespace to configure your model directly on your entity classes.
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace YourAppName.Models
{
public class Post
{
[Key] // Explicitly mark as Primary Key
public int PostId { get; set; } // Property name doesn't need to be 'Id' if Key is specified
[Required] // Makes the Title column NOT NULL
[MaxLength(200)] // Sets the max length of the string column
public string Title { get; set; }
[Column("PostContent")] // Maps to a column named 'PostContent'
public string Content { get; set; }
public DateTime PublishedDate { get; set; }
public int AuthorId { get; set; }
public Author Author { get; set; }
}
}
Fluent API
For more complex configurations or when you can't modify the entity classes, use the Fluent API within your DbContext
.
using Microsoft.EntityFrameworkCore;
namespace YourAppName.Data
{
public class AppDbContext : DbContext
{
public DbSet<Post> Posts { get; set; }
public DbSet<Author> Authors { get; set; }
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Post>()
.HasKey(p => p.PostId); // Explicitly set primary key
modelBuilder.Entity<Post>()
.Property(p => p.Title)
.IsRequired()
.HasMaxLength(200);
modelBuilder.Entity<Post>()
.Property(p => p.Content)
.HasColumnName("PostContent"); // Map to 'PostContent' column
modelBuilder.Entity<Post>()
.HasOne(p => p.Author) // Define one-to-one or one-to-many relationship
.WithMany(a => a.Posts)
.HasForeignKey(p => p.AuthorId); // Define foreign key
}
}
}
Relationships
EF Core supports various relationships, including one-to-one, one-to-many, and many-to-many. These are typically defined using navigation properties and foreign keys.
One-to-Many Example
The Post
and Author
example above demonstrates a one-to-many relationship: one author can have many posts. The AuthorId
in the Post
entity acts as the foreign key.
ICollection<T>
or by assigning an empty list in the constructor) to avoid null reference exceptions when accessing them.
Key Takeaways
- Models are represented by POCO classes (entities).
DbContext
is your gateway to the database.DbSet
represents a table of entities.- Configure your model using data annotations or the Fluent API.
- Define relationships using navigation properties and foreign keys.