Entity Framework Core

Saving Data

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
    }
}