Entity Framework
01 / 02

DbContext, LINQ Queries & Change Tracking

DbContext, LINQ Queries & Change Tracking

DbContext & DbSet

public class AppDbContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Post> Posts { get; set; }
}

var activeUsers = context.Users
    .Where(u => u.IsActive)
    .OrderBy(u => u.Name)
    .ToList();
// LINQ translates to actual SQL WHERE/ORDER BY — not fetch-all-then-filter

DbContext is the session with the database; each DbSet<T> maps to a table. LINQ queries against a DbSet get translated into real SQL by EF Core — a key ORM convenience.

Change Tracking & SaveChanges

var user = context.Users.Find(1);
user.Name = "Ada Lovelace";  // just a normal property set
context.SaveChanges();       // EF diffs and generates the right UPDATE

EF tracks what actually changed since load and generates INSERT/UPDATE/DELETE accordingly — no manual SQL needed. All changes in one SaveChanges() call are wrapped in a single transaction by default — all succeed or all fail together.

Eager vs. Lazy Loading & N+1

// eager — one (or few) queries fetch everything upfront
var posts = context.Posts.Include(p => p.Author).ToList();

// lazy — accessing .Author for EACH post in a loop triggers N extra queries
foreach (var post in posts) { Console.WriteLine(post.Author.Name); }  // N+1!

Navigation properties (post.Author) expose related data as objects. Unintentional lazy loading inside a loop is the classic N+1 pitfall — Include() eagerly fetches related data in the same query pass to avoid it.

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free