EF Core 8 Update Entity
Tags: csharp, database, dotnetcore
Published: 2024-06-13 20:39:56

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

```csharp
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; }
}
```

## Example 1

Read data.

```csharp
await using var context = new Context();
Person person = context.Person.FirstOrDefault();
```

Change FirstName and LastName.

```csharp
person.FirstName = "Jane";
person.LastName = "Adams";
```

Here the LastName is marked as not modified.

```csharp
context.Entry(person).Property(p => p.LastName).IsModified = false;
```

Save changes.

```csharp
var saveChanges = await context.SaveChangesAsync();
```

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;
```

Now, let's update the LastName.

```csharp
person.LastName = "Cater";
saveChanges = await context.SaveChangesAsync();
```

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;
```

## Example 2

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

```csharp
public class PersonModel
{
    public int Id { get; set; }
    public string FirstName { get; set; }
}
```

Here we create a detached Person.

```csharp
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();
```

1. Create a new Person.
1. Set the Id property to 2.
1. Create an instance of PersonModel with properties set.
1. Attach the new Person which will now be tracked by the change tracker.
1. Set the new Person instance values to the properties of the PersonModel.
1. 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;
```

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

{% cta https://github.com/karenpayneoregon/ef-code-8-samples/tree/master/SetPropertyValuesSample %} Sample project {% endcta %}

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.