Entity Framework Core CRUD Operations
This document provides a comprehensive guide to performing Create, Read, Update, and Delete (CRUD) operations using Entity Framework Core (EF Core) in your .NET applications.
Introduction to CRUD with EF Core
Entity Framework Core simplifies database interactions by allowing you to work with your database using C# objects. CRUD operations are fundamental to most applications that interact with a data store. EF Core provides intuitive methods for managing these operations.
1. Creating (Adding) New Entities
To add a new entity to your database, you first create an instance of your entity class, populate its properties, and then add it to the appropriate DbSet
in your DbContext
. Finally, call SaveChanges
to persist the changes to the database.
Example: Adding a new Product
using (var context = new MyDbContext())
{
var newProduct = new Product
{
Name = "Wireless Mouse",
Price = 25.99m,
StockQuantity = 150
};
context.Products.Add(newProduct);
await context.SaveChangesAsync(); // For async
// context.SaveChanges(); // For sync
}
2. Reading (Retrieving) Entities
EF Core offers various ways to query data, from simple retrieval of all entities to complex filtering, sorting, and projection.
Retrieving All Entities
using (var context = new MyDbContext())
{
var allProducts = await context.Products.ToListAsync();
// Process allProducts
}
Retrieving a Single Entity by ID
using (var context = new MyDbContext())
{
var productId = 1;
var product = await context.Products.FindAsync(productId); // Efficiently finds by primary key
// or
var productById = await context.Products.FirstOrDefaultAsync(p => p.Id == productId);
}
Filtering and Querying
Use LINQ to construct powerful queries. EF Core translates these LINQ queries into SQL.
using (var context = new MyDbContext())
{
var expensiveProducts = await context.Products
.Where(p => p.Price > 50.00m)
.OrderByDescending(p => p.Price)
.ToListAsync();
}
ToListAsync()
, FirstOrDefaultAsync()
, etc., for asynchronous operations to avoid blocking the UI thread in applications.
3. Updating Entities
To update an existing entity, you first retrieve it from the database, modify its properties, and then call SaveChanges
. EF Core tracks changes to entities in its context.
Example: Updating a Product's Price
using (var context = new MyDbContext())
{
var productToUpdate = await context.Products.FindAsync(productId);
if (productToUpdate != null)
{
productToUpdate.Price = 29.99m;
productToUpdate.StockQuantity -= 10;
await context.SaveChangesAsync();
}
}
// Assuming 'detachedProduct' is an entity not currently tracked by the context
context.Entry(detachedProduct).State = EntityState.Modified;
await context.SaveChangesAsync();
4. Deleting Entities
To delete an entity, you can either retrieve it and then call Remove
on the DbSet
, or directly specify the entity to be removed.
Example: Deleting a Product
using (var context = new MyDbContext())
{
var productToDelete = await context.Products.FindAsync(productId);
if (productToDelete != null)
{
context.Products.Remove(productToDelete);
await context.SaveChangesAsync();
}
}
Alternatively, you can remove an entity by its key if it's not currently tracked:
using (var context = new MyDbContext())
{
var productToDelete = new Product { Id = productId }; // Only Id is needed for Remove
context.Products.Remove(productToDelete);
await context.SaveChangesAsync();
}
Best Practices and Performance Considerations
- Asynchronous Operations: Always prefer asynchronous methods (e.g.,
ToListAsync()
,SaveChangesAsync()
) for I/O-bound operations. - Change Tracking: Understand EF Core's change tracking. When you retrieve an entity, EF Core tracks its state. When you call
SaveChanges
, it generates the appropriate SQL (INSERT, UPDATE, DELETE). - Disposed Context: Ensure your
DbContext
is properly disposed of. Using ausing
statement is the most common and recommended approach. - Batching Operations: For large numbers of operations, consider techniques like batching (using libraries like `EntityFrameworkCore.BatchUpdate`) to reduce the number of round trips to the database, though EF Core's default
SaveChanges
is optimized for many common scenarios. - Query Optimization: Use LINQ features effectively and understand how EF Core translates them to SQL. Use tools like SQL Server Profiler or EF Core logging to analyze generated SQL.
By mastering these CRUD operations, you can build robust and data-driven applications with Entity Framework Core.