Operazioni CRUD con EF Core
Esegua operazioni di creazione, lettura, aggiornamento ed eliminazione usando il rilevamento delle modifiche di EF Core e SaveChanges.
Operazioni CRUD con EF Core è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.
Panoramica del CRUD in EF Core
EF Core gestisce tutte e quattro le operazioni CRUD — Create, Read, Update, Delete — tramite una combinazione di rilevamento delle modifiche e SaveChangesAsync(). Comprendere il change tracker è fondamentale per padroneggiare il CRUD.
Creazione: aggiunta di una nuova entità
Utilizzi DbSet.Add() o AddAsync() per contrassegnare un'entità come Added. Durante SaveChangesAsync(), EF Core genera un INSERT e valorizza la chiave autoincrementante.
var order = new Order
{
CustomerId = 5,
PlacedAt = DateTime.UtcNow,
Status = OrderStatus.Pending
};
await _db.Orders.AddAsync(order);
await _db.SaveChangesAsync();
Console.WriteLine(order.Id); // populated by DBAggiunta di un grafo di entità
L'aggiunta di un'entità padre con i relativi elementi figlio in un'unica chiamata inserisce l'intero grafo di oggetti. EF Core risolve automaticamente le relazioni FK.
var order = new Order
{
CustomerId = 5,
PlacedAt = DateTime.UtcNow,
Lines = new List<OrderLine>
{
new() { ProductId = 10, Quantity = 2, Price = 49.99m },
new() { ProductId = 11, Quantity = 1, Price = 19.99m }
}
};
_db.Orders.Add(order);
await _db.SaveChangesAsync();
// Inserts Order + 2 OrderLines in one transactionLettura: query con LINQ
EF Core traduce le espressioni LINQ in SQL. Componga le query usando Where, Select, OrderBy ecc., quindi le materializzi con ToListAsync o FirstOrDefaultAsync.
// Read all pending orders for a customer
var orders = await _db.Orders
.Where(o => o.CustomerId == 5 && o.Status == OrderStatus.Pending)
.OrderByDescending(o => o.PlacedAt)
.Select(o => new OrderSummaryDto
{
Id = o.Id,
Total = o.Lines.Sum(l => l.Quantity * l.Price),
Status = o.Status.ToString()
})
.ToListAsync();Lettura: ricerca di una singola entità
Per leggere una singola entità, utilizzi FindAsync (controlla prima il tracker) oppure FirstOrDefaultAsync / SingleOrDefaultAsync con un predicato.
// By PK (checks cache first)
var order = await _db.Orders.FindAsync(orderId);
// By predicate (always hits DB)
var latest = await _db.Orders
.Where(o => o.CustomerId == 5)
.OrderByDescending(o => o.PlacedAt)
.FirstOrDefaultAsync();Aggiornamento: rilevamento delle modifiche
Le entità caricate tramite EF Core vengono tracciate. Modifichi direttamente le proprietà e chiami SaveChangesAsync(). EF Core rileva la differenza e genera un'istruzione UPDATE minimale.
var order = await _db.Orders.FindAsync(orderId);
if (order is null) return;
order.Status = OrderStatus.Shipped;
order.ShippedAt = DateTime.UtcNow;
await _db.SaveChangesAsync();
// UPDATE Orders SET Status=..., ShippedAt=... WHERE Id=orderIdAggiornamento: aggiornamento di massa (EF Core 7+)
ExecuteUpdateAsync aggiorna direttamente le righe nel database senza caricare le entità. È molto più efficiente per le operazioni di massa.
// Mark all overdue orders as Cancelled — no loading needed
await _db.Orders
.Where(o => o.Status == OrderStatus.Pending
&& o.PlacedAt < DateTime.UtcNow.AddDays(-30))
.ExecuteUpdateAsync(set => set
.SetProperty(o => o.Status, OrderStatus.Cancelled)
.SetProperty(o => o.UpdatedAt, DateTime.UtcNow));Eliminazione: rimozione di una singola entità
Chiami Remove() su un'entità tracciata, quindi chiami SaveChangesAsync(). Se dispone solo dell'ID, lo cerchi prima oppure utilizzi ExecuteDeleteAsync.
var order = await _db.Orders.FindAsync(orderId);
if (order is null) return;
_db.Orders.Remove(order);
await _db.SaveChangesAsync();
// DELETE FROM Orders WHERE Id=orderIdEliminazione: eliminazione di massa (EF Core 7+)
ExecuteDeleteAsync esegue una singola istruzione SQL DELETE senza caricare le entità: è ideale per le operazioni di pulizia in batch.
// Delete all cancelled orders older than 1 year
int deleted = await _db.Orders
.Where(o => o.Status == OrderStatus.Cancelled
&& o.PlacedAt < DateTime.UtcNow.AddYears(-1))
.ExecuteDeleteAsync();
Console.WriteLine($"Deleted {deleted} old orders");Transazioni
Tutte le operazioni incluse in una singola chiamata a SaveChangesAsync vengono racchiuse in una transazione. Per operazioni composte da più passaggi e più salvataggi, utilizzi una transazione esplicita.
using var transaction = await _db.Database.BeginTransactionAsync();
try
{
_db.Orders.Add(newOrder);
await _db.SaveChangesAsync();
inventory.Stock -= newOrder.Quantity;
await _db.SaveChangesAsync();
await transaction.CommitAsync();
}
catch
{
await transaction.RollbackAsync();
throw;
}Esempio reale: servizio CRUD completo
Un servizio completo incapsula tutte le operazioni CRUD con una gestione appropriata degli errori e restituisce DTO per evitare di esporre i dettagli interni delle entità.
public async Task<OrderDto> CreateOrderAsync(CreateOrderRequest req)
{
var order = new Order { CustomerId = req.CustomerId, PlacedAt = DateTime.UtcNow };
_db.Orders.Add(order);
await _db.SaveChangesAsync();
return new OrderDto { Id = order.Id, Status = order.Status.ToString() };
}
public async Task<bool> CancelOrderAsync(int id)
{
int rows = await _db.Orders
.Where(o => o.Id == id && o.Status == OrderStatus.Pending)
.ExecuteUpdateAsync(s =>
s.SetProperty(o => o.Status, OrderStatus.Cancelled));
return rows > 0;
}Verifica rapida
Qual è il vantaggio di ExecuteUpdateAsync / ExecuteDeleteAsync rispetto a caricare le entità e chiamare SaveChangesAsync?
Riepilogo: operazioni CRUD con EF Core
Punti chiave:
- Add + SaveChangesAsync → INSERT; EF Core valorizza le chiavi generate automaticamente
- Modificare le entità tracciate + SaveChangesAsync → UPDATE minimale
- Remove + SaveChangesAsync → DELETE per le singole entità
- ExecuteUpdateAsync / ExecuteDeleteAsync → operazioni di massa senza caricare le entità (EF Core 7+)
- Racchiudere le operazioni composte da più passaggi in una transazione esplicita per garantirne l'atomicità
Domande Frequenti
La lezione «Operazioni CRUD con EF Core» è gratuita?
Sì — il testo completo di «Operazioni CRUD con EF Core» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.
Cosa imparerò in «Operazioni CRUD con EF Core»?
Esegua operazioni di creazione, lettura, aggiornamento ed eliminazione usando il rilevamento delle modifiche di EF Core e SaveChanges. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare C# Academy?
Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «Operazioni CRUD con EF Core»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione C# Academy?
Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Nozioni di base su DbContext e DbSet
- Migrazioni e gestione dello schema
- Operazioni CRUD con EF Core
- Relazioni: uno-a-molti e molti-a-molti