Entity Framework Core Concepts

Entity Framework Core (EF Core) is a modern, cross-platform Object-Relational Mapper (ORM) for .NET. It enables developers to work with a database using .NET objects that represent the data, eliminating the need for most of the data-access code they typically need to write.

DbContext

The DbContext is the primary class for interacting with Entity Framework Core. It represents a session with the database and allows you to query and save data. It's a gateway to your data. You typically create a class that derives from DbContext and adds DbSet<TEntity> properties for each entity in your model.


public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=MyDatabase;Trusted_Connection=True;");
    }
}
            

Entity Model

The entity model defines the shape of your data. It's composed of:

EF Core can discover your entity model through conventions or by explicit configuration using Data Annotations or the Fluent API.

DbSet

A DbSet<TEntity> property on your DbContext represents a collection of all entities of a given type in the context, or that can be queried from the database. DbSet is the primary way to query entities from the database.


using (var context = new BloggingContext())
{
    var blogs = context.Blogs.ToList(); // Query all blogs
}
            

Migrations

Migrations are a feature of EF Core that allows you to incrementally update your database schema to match your evolving entity model without having to manually write and manage database scripts. They are managed through the .NET CLI or Package Manager Console.

Key migration commands:

Note: Migrations help maintain consistency between your code model and your database schema.

Querying

EF Core translates LINQ queries written against your DbSet properties into SQL queries that are executed against the database. This allows you to query your data using familiar C# syntax.


using (var context = new BloggingContext())
{
    var posts = context.Posts
                       .Where(p => p.Title.Contains("EF Core"))
                       .OrderBy(p => p.PublishedDate)
                       .ToList();
}
            

EF Core supports eager loading, explicit loading, and lazy loading of related data.

Change Tracking

EF Core automatically tracks changes made to entities that are retrieved from the database through the DbContext. When you call SaveChanges(), EF Core compares the current state of the tracked entities with their original state and generates the appropriate SQL commands (INSERT, UPDATE, DELETE) to synchronize the database.


using (var context = new BloggingContext())
{
    var blogToUpdate = context.Blogs.Find(1);
    if (blogToUpdate != null)
    {
        blogToUpdate.Url = "https://new-url.com";
        context.SaveChanges(); // EF Core detects the change and issues an UPDATE
    }
}
            

Relationships

EF Core supports various types of relationships between entities:

These relationships are typically defined using navigation properties and configured using Fluent API or Data Annotations.

Entity Framework Core Relationship Diagram

Conceptual diagram of entity relationships in EF Core.

Saving Changes

The DbContext.SaveChanges() method is used to persist any changes made to tracked entities to the database. EF Core analyzes the state of all tracked entities and generates the necessary SQL commands. The SaveChangesAsync() method provides an asynchronous alternative.


using (var context = new BloggingContext())
{
    var newBlog = new Blog { Url = "https://example.com" };
    context.Blogs.Add(newBlog);

    var post = context.Posts.Find(5);
    if (post != null)
    {
        post.Content = "Updated content.";
    }

    context.SaveChanges(); // Persists both the new blog and the updated post
}