Saving Data with EF Core

Entity Framework Core (EF Core) provides a straightforward and powerful way to save data to your database. This involves tracking changes to entities and then persisting those changes.

The SaveChanges() Method

The primary method for saving changes in EF Core is SaveChanges(), which is called on your DbContext instance. This method inspects all tracked entities for changes and generates the necessary SQL commands to update the database.

Adding New Entities

To add a new entity, you first create an instance of your entity class and then add it to the appropriate DbSet in your DbContext. EF Core will then track this new entity as added.


using (var context = new MyDbContext())
{
    var newUser = new User { Name = "Alice", Email = "alice@example.com" };
    context.Users.Add(newUser);
    await context.SaveChangesAsync(); // Inserts the new user
}
            

Modifying Existing Entities

EF Core automatically tracks changes made to entities that have been retrieved from the database. When you modify a property of a tracked entity, EF Core detects the change.


using (var context = new MyDbContext())
{
    var userToUpdate = await context.Users.FindAsync(1); // Assume user with ID 1 exists
    if (userToUpdate != null)
    {
        userToUpdate.Email = "alice.updated@example.com";
        await context.SaveChangesAsync(); // Updates the user's email
    }
}
            

Removing Entities

To remove an entity, you typically retrieve it from the database and then call the Remove() method on the corresponding DbSet.


using (var context = new MyDbContext())
{
    var userToRemove = await context.Users.FindAsync(2); // Assume user with ID 2 exists
    if (userToRemove != null)
    {
        context.Users.Remove(userToRemove);
        await context.SaveChangesAsync(); // Deletes the user
    }
}
            

Handling Multiple Operations

You can perform multiple add, modify, and remove operations within a single DbContext instance before calling SaveChangesAsync(). EF Core will efficiently batch these operations.


using (var context = new MyDbContext())
{
    var newUser = new User { Name = "Bob", Email = "bob@example.com" };
    context.Users.Add(newUser);

    var existingUser = await context.Users.FindAsync(1);
    if (existingUser != null)
    {
        existingUser.Name = "Alice Smith";
    }

    var userToRemove = await context.Users.FindAsync(3);
    if (userToRemove != null)
    {
        context.Users.Remove(userToRemove);
    }

    await context.SaveChangesAsync(); // Performs all tracked operations
}
            

Concurrency Control

EF Core supports optimistic concurrency control to handle cases where multiple users might try to modify the same data simultaneously. By default, EF Core uses a simple "last writer wins" approach. For more robust concurrency handling, you can configure conflict-detection strategies.

Note: For production applications, it's highly recommended to implement appropriate concurrency control mechanisms to prevent data loss.

SaveChangesAsync() vs. SaveChanges()

It's generally recommended to use the asynchronous version, SaveChangesAsync(), in applications where responsiveness is important, such as web applications or UIs. This prevents blocking the current thread while the database operation completes.

Optimizing Performance

When saving many entities, consider using SaveChanges(true) or SaveChanges(false) as per your application's needs, although the default behavior is usually sufficient.

Tip: For bulk operations, consider using EF Core's bulk operations extensions or other specialized libraries if performance is critical.