After this lesson, you will be able to: Use Entity Framework Core: code-first migrations, DbContext, LINQ queries, relationships, performance traps.
EF Core is the standard .NET ORM. Code-first migrations + LINQ queries that translate to SQL = productive but with footguns around N+1 and lazy loading.
Models are POCOs; DbContext is your unit of work.
// Modelspublic class User {public int Id { get; set; }public string Name { get; set; } = "";public string Email { get; set; } = "";public List<Post> Posts { get; set; } = new();}public class Post {public int Id { get; set; }public string Title { get; set; } = "";public int UserId { get; set; }public User User { get; set; } = null!;}// DbContextpublic class AppDbContext : DbContext {public DbSet<User> Users => Set<User>();public DbSet<Post> Posts => Set<Post>();protected override void OnConfiguring(DbContextOptionsBuilder options) {options.UseNpgsql("Host=localhost;Database=mydb;Username=postgres;Password=...");// Or: options.UseSqlServer(connStr) / UseSqlite(connStr)}}// In Program.csbuilder.Services.AddDbContext<AppDbContext>(options =>options.UseNpgsql(builder.Configuration.GetConnectionString("Default")));
Code-first workflow.
# Install EF tool (one-time)dotnet tool install --global dotnet-ef# Add EF Core packagesdotnet add package Microsoft.EntityFrameworkCore.Designdotnet add package Microsoft.EntityFrameworkCore.Npgsql# Add a migrationdotnet ef migrations add InitialCreate# Apply to databasedotnet ef database update# Roll backdotnet ef migrations remove# Generate SQL script (don't apply)dotnet ef migrations script
LINQ queries translate to SQL automatically.
using var db = new AppDbContext();// Simple findvar user = await db.Users.FindAsync(1);// Where + Select (translates to SQL)var names = await db.Users.Where(u => u.Name.StartsWith("A")).Select(u => u.Name).ToListAsync();// Eager loading (avoids N+1)var usersWithPosts = await db.Users.Include(u => u.Posts).ToListAsync();// Async pagingvar page = await db.Users.OrderBy(u => u.Name).Skip(10).Take(10).ToListAsync();// Insertawait db.SaveChangesAsync();// Update, change tracker auto-detects changesvar u = await db.Users.FindAsync(1);await db.SaveChangesAsync();// Deletedb.Users.Remove(u);await db.SaveChangesAsync();
Forgetting Include() → N+1 queries in prod. Singleton DbContext → corrupted state. Loading entire table for a count (use `.CountAsync()` not `.ToListAsync().Count`). Saving inside a loop (call SaveChangesAsync ONCE at the end of a batch).
Sign in and purchase access to unlock this lesson.