DEV Community

Cover image for EF Core 8 Update Entity
Karen Payne
Karen Payne

Posted on

EF Core 8 Update Entity

When entities are being tracked (this is the default, to track changes) EF Core is efficient with updates in that if there are several properties for a model and only one or two properties changed the update statement only updates those columns/properties which changed rather than every column/property.

Model

public partial class Person
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateOnly BirthDate { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Example 1

Read data.

await using var context = new Context();
Person person = context.Person.FirstOrDefault();
Enter fullscreen mode Exit fullscreen mode

Change FirstName and LastName.

person.FirstName = "Jane";
person.LastName = "Adams";
Enter fullscreen mode Exit fullscreen mode

Here the LastName is marked as not modified.

context.Entry(person).Property(p => p.LastName).IsModified = false;
Enter fullscreen mode Exit fullscreen mode

Save changes.

var saveChanges = await context.SaveChangesAsync();
Enter fullscreen mode Exit fullscreen mode

Using a log file to see what EF Core generated for the above, note only FirstName was updated.

info: 6/13/2024 06:36:37.171 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command) 
      Executed DbCommand (27ms) [Parameters=[@p1='1', @p0='Jane' (Nullable = false) (Size = 4000)], CommandType='Text', CommandTimeout='30']
      SET IMPLICIT_TRANSACTIONS OFF;
      SET NOCOUNT ON;
      UPDATE [Person] SET [FirstName] = @p0
      OUTPUT 1
      WHERE [Id] = @p1;
Enter fullscreen mode Exit fullscreen mode

Now, let's update the LastName.

person.LastName = "Cater";
saveChanges = await context.SaveChangesAsync();
Enter fullscreen mode Exit fullscreen mode

Log file entry, only LastName property was updated.

info: 6/13/2024 06:36:37.188 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command) 
      Executed DbCommand (1ms) [Parameters=[@p1='1', @p0='Cater' (Nullable = false) (Size = 4000)], CommandType='Text', CommandTimeout='30']
      SET IMPLICIT_TRANSACTIONS OFF;
      SET NOCOUNT ON;
      UPDATE [Person] SET [LastName] = @p0
      OUTPUT 1
      WHERE [Id] = @p1;
Enter fullscreen mode Exit fullscreen mode

Example 2

Continued from the first example. Here a super simple model is introduced, think of it as a DTO (Data Transfer Object).

public class PersonModel
{
    public int Id { get; set; }
    public string FirstName { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Here we create a detached Person.

int identifier = 2;
person = new() { Id = identifier };
PersonModel model = new() { Id = identifier, FirstName = "Greg" };

context.Attach(person);
context.Entry(person).CurrentValues.SetValues(model);
saveChanges = await context.SaveChangesAsync();
Enter fullscreen mode Exit fullscreen mode
  1. Create a new Person.
  2. Set the Id property to 2.
  3. Create an instance of PersonModel with properties set.
  4. Attach the new Person which will now be tracked by the change tracker.
  5. Set the new Person instance values to the properties of the PersonModel.
  6. Save changes.

Log file

info: 6/13/2024 06:36:37.197 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command) 
      Executed DbCommand (1ms) [Parameters=[@p1='2', @p0='Greg' (Nullable = false) (Size = 4000)], CommandType='Text', CommandTimeout='30']
      SET IMPLICIT_TRANSACTIONS OFF;
      SET NOCOUNT ON;
      UPDATE [Person] SET [FirstName] = @p0
      OUTPUT 1
      WHERE [Id] = @p1;
Enter fullscreen mode Exit fullscreen mode

What's the point?

To show that EF Core is efficient with updates which is important more so for web applications than desktop applications, less traffic, quicker response to and from a database.

Source code

Sample project

Although the above samples are simple, in the source code try experimenting.

Source code notes

  • Each time the project runs the database is recreated.
  • Data is generated in the class MockedData.
  • Data from above is assigned under Data\Context class in OnModelCreating method.

Top comments (0)