Introduction to Saving Data
Entity Framework Core (EF Core) simplifies data persistence by allowing you to work with your domain entities directly. When you need to save changes made to these entities—whether adding new ones, modifying existing ones, or deleting them—EF Core handles the translation to SQL commands.
Key Concept: The DbContext is your gateway to the database. It tracks changes to your entities and is responsible for executing the SQL commands to persist those changes.
Adding New Entities
To add a new entity, you typically create an instance of your entity class and then attach it to the DbContext using the Add() method.
Example: Adding a Blog
public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List<Post> Posts { get; set; } }
using (var context = new MyDbContext())
{
var newBlog = new Blog { Url = "http://sample.com" };
context.Blogs.Add(newBlog); // Or context.Add(newBlog);
context.SaveChanges();
}
Modifying Existing Entities
When you retrieve an entity from the database using EF Core, the DbContext is already tracking it. Any modifications you make to the properties of a tracked entity are automatically detected when SaveChanges() is called. EF Core will then generate the appropriate UPDATE SQL statement.
Example: Updating a Blog's URL
using (var context = new MyDbContext())
{
var blogToUpdate = context.Blogs
.First(b => b.BlogId == 1);
blogToUpdate.Url = "http://updated-sample.com";
context.SaveChanges(); // UPDATE statement generated automatically
}
No Explicit Tracking Needed: If an entity is retrieved by EF Core from the same context, you don't need to re-attach it or explicitly mark it as modified. Simply change its properties.
Deleting Entities
To delete an entity, you can retrieve it from the database and then use the Remove() method on the DbContext.
Example: Deleting a Blog
using (var context = new MyDbContext())
{
var blogToDelete = context.Blogs
.Find(2); // Find is efficient for primary key lookups
if (blogToDelete != null)
{
context.Blogs.Remove(blogToDelete); // Or context.Remove(blogToDelete);
context.SaveChanges(); // DELETE statement generated
}
}
Saving Multiple Changes
You can perform multiple operations (add, update, delete) within a single SaveChanges() call. EF Core will batch these operations and execute them efficiently.
Example: Multiple Operations
using (var context = new MyDbContext())
{
// Add a new blog
var blog1 = new Blog { Url = "http://blog1.com" };
context.Add(blog1);
// Update an existing blog
var blogToUpdate = context.Blogs.Find(3);
if (blogToUpdate != null)
{
blogToUpdate.Url = "http://updated-blog3.com";
}
// Mark another blog for deletion
var blogToDelete = context.Blogs.Find(4);
if (blogToDelete != null)
{
context.Remove(blogToDelete);
}
int affectedRows = context.SaveChanges();
// affectedRows will be the total number of rows affected by all operations
}
DbContext.SaveChanges() vs. DbContext.SaveChangesAsync()
For asynchronous operations, which are highly recommended in web applications to prevent blocking threads, use SaveChangesAsync().
Example: Asynchronous Save
public async Task AddBlogAsync(string url)
{
using (var context = new MyDbContext())
{
var newBlog = new Blog { Url = url };
context.Blogs.Add(newBlog);
await context.SaveChangesAsync(); // Asynchronous save
}
}