Entity Framework Core - Data Operations đď¸
Imagine you have a magical notebook that can talk to a giant library. You write what you want, and the notebook fetches, adds, updates, or removes books for you. Thatâs Entity Framework Core (EF Core)! Itâs your magical translator between your C# code and your database.
đŻ What Weâll Learn
Think of a restaurant kitchen:
- CRUD = Taking orders, cooking food, updating orders, throwing away bad food
- LINQ = A special language to describe exactly what food you want
- Tracking = The chef remembering whatâs cooking vs. just peeking at the menu
- Loading Strategies = Getting ingredients when you need them
- N+1 Problem = Asking for ingredients one by one instead of all at once
- Relationships = How ingredients connect (eggs belong to breakfast, not dessert!)
1. CRUD Operations đł
CRUD stands for Create, Read, Update, Delete. These are the 4 things you can do with dataâlike a librarian managing books!
Create (Add New Things)
// Create a new student
var student = new Student
{
Name = "Emma",
Age = 10
};
context.Students.Add(student);
await context.SaveChangesAsync();
What happens? You tell EF Core: âHey, I have a new student named Emma. Please save her to the database!â
Read (Find Things)
// Find all students
var allStudents = await context
.Students
.ToListAsync();
// Find one student by ID
var emma = await context
.Students
.FindAsync(1);
What happens? You ask: âShow me all the students!â or âFind student #1!â
Update (Change Things)
// Find Emma and change her age
var emma = await context
.Students
.FindAsync(1);
emma.Age = 11; // Birthday!
await context.SaveChangesAsync();
What happens? You found Emma, changed her age, then told EF Core: âSave these changes!â
Delete (Remove Things)
// Remove a student
var student = await context
.Students
.FindAsync(1);
context.Students.Remove(student);
await context.SaveChangesAsync();
What happens? âPlease remove this student from the database.â
graph TD A["Your Code"] --> B{CRUD Operation} B --> C["Create: Add"] B --> D["Read: Find/ToList"] B --> E["Update: Modify + Save"] B --> F["Delete: Remove"] C --> G["Database"] D --> G E --> G F --> G
2. LINQ with EF Core đ
LINQ (Language Integrated Query) is like ordering food at a restaurant. Instead of going to the kitchen yourself, you describe what you want!
Basic Queries
// Find students older than 8
var olderKids = await context.Students
.Where(s => s.Age > 8)
.ToListAsync();
// Get just the names
var names = await context.Students
.Select(s => s.Name)
.ToListAsync();
// Order by age
var sorted = await context.Students
.OrderBy(s => s.Age)
.ToListAsync();
Combining Filters
// Find students named "Emma" who are 10+
var result = await context.Students
.Where(s => s.Name == "Emma")
.Where(s => s.Age >= 10)
.FirstOrDefaultAsync();
Counting and Checking
// How many students?
var count = await context.Students
.CountAsync();
// Is there anyone named "Liam"?
var exists = await context.Students
.AnyAsync(s => s.Name == "Liam");
Think of it like this:
Where= âI only want students whoâŚâSelect= âI only want to see theâŚâOrderBy= âSort them byâŚâFirstOrDefault= âGive me the first one, or nothingâ
3. Tracking vs No-Tracking đ
Imagine youâre a chef. Tracking means you remember every dish youâre cooking so you can update it. No-Tracking means you just peek at the menuâyouâre not planning to cook anything.
Tracking (Default)
// EF Core remembers this student
var student = await context.Students
.FirstAsync();
student.Name = "Updated Name";
await context.SaveChangesAsync();
// â
Changes are saved!
EF Core keeps an eye on student. When you change it and save, the database updates!
No-Tracking (Just Looking)
// EF Core forgets immediately
var student = await context.Students
.AsNoTracking()
.FirstAsync();
student.Name = "New Name";
await context.SaveChangesAsync();
// â Nothing saved! EF Core forgot.
When to use No-Tracking?
- When youâre just displaying data (read-only)
- Itâs faster because EF Core doesnât need to remember
graph TD A["Query Data"] --> B{Will you change it?} B -->|Yes| C["Use Tracking"] B -->|No, just reading| D["Use AsNoTracking"] C --> E["Changes saved automatically"] D --> F["Faster, but no saves"]
4. EF Core Loading Strategies đŚ
When you have related data (like a student and their classes), how should EF Core fetch them?
Eager Loading (Get Everything Now!)
// Get students WITH their classes
var students = await context.Students
.Include(s => s.Classes)
.ToListAsync();
Like ordering a combo mealâyou get the burger AND fries together!
Lazy Loading (Get It When Needed)
// Classes load automatically when accessed
var student = await context.Students
.FirstAsync();
var classes = student.Classes;
// Database call happens HERE
Like asking for ketchup only when you need it. But be carefulâtoo many small trips!
Explicit Loading (Ask Specifically)
var student = await context.Students
.FirstAsync();
// Load classes ONLY when I say so
await context.Entry(student)
.Collection(s => s.Classes)
.LoadAsync();
You decide exactly when to fetch related data.
| Strategy | When to Use | Speed |
|---|---|---|
| Eager | Need related data immediately | 1 big query |
| Lazy | Might need it, might not | Many small queries |
| Explicit | Control freak mode | You decide |
5. The N+1 Query Problem đ
This is a sneaky performance trap! Letâs see it with a story.
The Problem
Imagine you have 100 students, and each has classes. You want to show them all.
Bad Way (N+1):
var students = await context.Students
.ToListAsync();
foreach (var s in students)
{
// Each loop = NEW database query!
Console.WriteLine(s.Classes.Count);
}
// Total: 1 + 100 = 101 queries! đą
You made 1 query for students, then 100 MORE for each studentâs classes!
The Solution
Good Way (Eager Loading):
var students = await context.Students
.Include(s => s.Classes)
.ToListAsync();
foreach (var s in students)
{
Console.WriteLine(s.Classes.Count);
}
// Total: 1 query! đ
graph LR A["N+1 Problem"] --> B["1 Query: Get Students"] B --> C["Query 2: Student 1 Classes"] B --> D["Query 3: Student 2 Classes"] B --> E["Query 4: Student 3 Classes"] B --> F["... 100 more queries!"] G["Solution: Eager Loading"] --> H["1 Query: Students + Classes"] H --> I["Done! No extra queries"]
Remember: If youâre looping and accessing related data, use Include()!
6. EF Core Relationships đ
Databases have relationshipsâjust like friends, families, and teams!
One-to-Many (Parent has Many Children)
public class Teacher
{
public int Id { get; set; }
public string Name { get; set; }
// One teacher has MANY students
public List<Student> Students { get; set; }
}
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
// Each student has ONE teacher
public int TeacherId { get; set; }
public Teacher Teacher { get; set; }
}
One-to-One (One Person, One Passport)
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
// One student, one ID card
public StudentIdCard IdCard { get; set; }
}
public class StudentIdCard
{
public int Id { get; set; }
public string CardNumber { get; set; }
public int StudentId { get; set; }
public Student Student { get; set; }
}
Many-to-Many (Students â Classes)
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
// Many students in many classes
public List<Class> Classes { get; set; }
}
public class Class
{
public int Id { get; set; }
public string Subject { get; set; }
// Many classes have many students
public List<Student> Students { get; set; }
}
EF Core 5+ handles the join table automatically!
graph LR subgraph One-to-Many A["Teacher"] -->|has many| B["Students"] end subgraph One-to-One C["Student"] -->|has one| D["ID Card"] end subgraph Many-to-Many E["Students"] <-->|enrolled in| F["Classes"] end
Loading Related Data
// Get teacher with all students
var teacher = await context.Teachers
.Include(t => t.Students)
.FirstAsync(t => t.Id == 1);
// Get student with classes
var student = await context.Students
.Include(s => s.Classes)
.FirstAsync(s => s.Id == 1);
đ Quick Summary
| Concept | Simple Explanation |
|---|---|
| CRUD | Create, Read, Update, Deleteâthe 4 data actions |
| LINQ | Ask for data using C# instead of SQL |
| Tracking | EF Core remembers changes to save later |
| No-Tracking | Just looking, no savingâfaster! |
| Eager Loading | Get everything in one trip |
| Lazy Loading | Get extra stuff only when needed |
| N+1 Problem | Making too many database tripsâbad! |
| Relationships | How tables connect (1-to-1, 1-to-many, many-to-many) |
đ You did it! You now understand how EF Core talks to your database. Itâs like having a super-smart assistant that translates your C# wishes into database actions. Keep practicing, and soon itâll feel like magic! â¨
