Courses/C#/EF Core Internals
    Back to Course

    Lesson 33: Entity Framework Core Internals & Performance

    Understand how EF Core tracks entities, generates SQL, and how to write efficient database queries.

    What You'll Learn

    • • DbContext, DbSet, and entity configuration
    • • LINQ-to-SQL translation and eager/lazy loading
    • • Change tracking states (Added, Modified, Unchanged, Deleted)
    • • AsNoTracking, projections, and performance best practices

    🧠 Real-World Analogy

    EF Core is like a personal assistant who translates between you (C#) and a foreign business partner (the database). You say "find products over $100 sorted by name" in C#, and the assistant writes the SQL query, sends it, and hands you back C# objects. Change tracking is like the assistant keeping a notepad of everything you changed, then sending all updates at once when you say "save."

    DbContext & Entity Configuration

    DbContext is the central class in EF Core. It represents a session with the database, holds DbSet<T> properties for each table, and manages change tracking. You configure entities with Data Annotations on the class or Fluent API in OnModelCreating.

    DbContext, Entities & Fluent API

    Set up a database context with entity configuration and seed data.

    Try it Yourself »
    C#
    using System;
    using Microsoft.EntityFrameworkCore;
    using System.ComponentModel.DataAnnotations;
    
    // Entity classes
    public class Product
    {
        public int Id { get; set; }
        
        [Required, MaxLength(100)]
        public string Name { get; set; } = "";
        
        public decimal Price { get; set; }
        
        [MaxLength(50)]
        public string Category { get; set; } = "";
        
        public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
        
        // Navigation property (one-to-many)
        public List<Revie
    ...

    LINQ Queries & Loading Strategies

    EF Core translates LINQ expressions to SQL. Use Include() for eager loading related data, Select() for projections (fetching only needed columns), and AsNoTracking() for read-only queries that skip change tracking overhead.

    LINQ Queries, Include & Projections

    Write efficient queries with eager loading, projections, and AsNoTracking.

    Try it Yourself »
    C#
    using System;
    using System.Linq;
    using Microsoft.EntityFrameworkCore;
    
    // Assume AppDbContext from previous example
    class Program
    {
        static void Main()
        {
            using var db = new AppDbContext();
            db.Database.EnsureCreated();
            
            // === Basic LINQ queries (translated to SQL) ===
            
            // SELECT * FROM Products WHERE Price > 100 ORDER BY Name
            var expensive = db.Products
                .Where(p => p.Price > 100)
                .OrderBy(p => p.Name)
            
    ...

    Change Tracking

    EF Core's change tracker monitors every entity loaded from the database. When you modify properties, it detects the changes automatically. SaveChanges() generates the minimal SQL needed — only UPDATE the columns that actually changed.

    Change Tracking States & SaveChanges

    Observe entity states and see how EF Core generates minimal SQL.

    Try it Yourself »
    C#
    using System;
    using Microsoft.EntityFrameworkCore;
    
    class Program
    {
        static void Main()
        {
            using var db = new AppDbContext();
            db.Database.EnsureCreated();
            
            // === Change Tracking — EF tracks entity state ===
            Console.WriteLine("=== Change Tracking Demo ===
    ");
            
            // 1. Load an entity (state: Unchanged)
            var product = db.Products.First();
            Console.WriteLine($"Loaded: {product.Name} (State: {db.Entry(product).State})");
         
    ...
    Entity StateMeaningSQL Generated
    AddedNew entity, not yet in DBINSERT
    UnchangedLoaded, not modifiedNone
    ModifiedProperty values changedUPDATE (changed cols only)
    DeletedMarked for removalDELETE
    DetachedNot tracked by contextNone

    Pro Tip

    Use ExecuteUpdate and ExecuteDelete (EF Core 7+) for bulk operations that bypass change tracking entirely. They translate directly to UPDATE/DELETE SQL without loading entities into memory.

    Common Mistakes

    • • N+1 queries — forgetting Include() causes a query per related entity
    • • Loading entire entities when you only need 2 columns — use Select()
    • • Long-lived DbContext — keep it short-lived (scoped per request)

    Lesson Complete!

    You understand EF Core's internals. Next, master relationships, tracking strategies, and migrations.

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service