8 minlesson

CRUD Operations Overview

CRUD Operations Overview

CRUD stands for Create, Read, Update, Delete -- the four fundamental operations for working with data. In EF Core, you perform these operations using C# methods on your DbContext and DbSet, and then persist changes by calling SaveChanges.

The Core Workflow

Every data operation in EF Core follows the same pattern:

  1. Get a DbContext instance (via dependency injection or manual creation)
  2. Perform operations on entities through DbSet properties
  3. Call SaveChanges to persist modifications to the database
csharp
1using var context = new AppDbContext();
2
3// Create
4var product = new Product { Name = "Widget", Price = 9.99m };
5context.Products.Add(product);
6
7// SaveChanges generates and executes the SQL
8await context.SaveChangesAsync();

EF Core does not immediately execute SQL when you call Add, Remove, or modify a property. Instead, the Change Tracker records your intent, and SaveChanges translates all pending changes into SQL statements in a single batch.

The Key Methods

Here is a summary of the primary EF Core methods for each CRUD operation:

OperationMethodsWhat It Does
CreateAdd, AddRange, AddAsyncMarks entities as Added in the Change Tracker
ReadFind, FirstOrDefault, SingleOrDefault, Where, ToListQueries the database and returns entities
UpdateModify tracked properties, Update, AttachMarks entities or properties as Modified
DeleteRemove, RemoveRange, ExecuteDeleteMarks entities as Deleted or performs bulk delete
PersistSaveChanges, SaveChangesAsyncGenerates SQL and executes all pending changes

How the Change Tracker Fits In

The Change Tracker is central to CRUD operations. When EF Core loads an entity from the database, it takes a snapshot of the original values. When you call SaveChanges, it compares current values to the snapshot and generates the appropriate SQL:

1Entity loaded → Original snapshot stored
2
3Properties modified in C#
4
5SaveChanges() called
6
7Change Tracker compares current vs. original
8
9SQL generated only for changed properties
10
11Database updated

This means you do not need to tell EF Core which properties changed. It detects the differences automatically.

Entity States

Every entity tracked by EF Core is in one of these states:

StateMeaningSaveChanges Behavior
AddedNew entity, not yet in the databaseGenerates INSERT
UnchangedLoaded from DB, no modificationsNo SQL generated
ModifiedLoaded from DB, properties changedGenerates UPDATE
DeletedMarked for removalGenerates DELETE
DetachedNot tracked by the contextIgnored by SaveChanges

You can inspect an entity's state at any time:

csharp
1var entry = context.Entry(product);
2Console.WriteLine(entry.State); // Added, Modified, etc.

Async vs. Sync Methods

EF Core provides both synchronous and asynchronous versions of most methods:

SyncAsyncUse When
Add()AddAsync()AddAsync is needed only for value generators that require DB access
SaveChanges()SaveChangesAsync()Always prefer async in web apps
Find()FindAsync()Always prefer async in web apps
ToList()ToListAsync()Always prefer async in web apps

In practice, always use async methods in ASP.NET Core and other I/O-bound applications. The synchronous versions are mainly useful in console scripts or tests.

SaveChanges as a Unit of Work

A key concept in EF Core is that SaveChanges commits all pending changes as a single unit of work. If you add two entities and modify a third, all three operations execute within an implicit database transaction:

csharp
1context.Products.Add(product1);
2context.Products.Add(product2);
3existingProduct.Price = 19.99m;
4
5// All three changes are saved in one transaction
6await context.SaveChangesAsync();

If any operation fails, the entire batch is rolled back and no partial changes are persisted. This guarantees data consistency without requiring you to manage transactions manually for most scenarios.

Summary

  • CRUD operations are performed through DbSet methods on a DbContext
  • The Change Tracker records all pending changes until SaveChanges is called
  • SaveChanges batches all changes into a single database transaction
  • Every tracked entity has a state (Added, Modified, Deleted, Unchanged, Detached)
  • Prefer async methods in web applications and I/O-bound code

In the following presentations, we will explore each CRUD operation in detail with practical code examples.