EF Core 8 Update Entity
Karen Payne
Posted on June 13, 2024
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; }
}
Example 1
Read data.
await using var context = new Context();
Person person = context.Person.FirstOrDefault();
Change FirstName and LastName.
person.FirstName = "Jane";
person.LastName = "Adams";
Here the LastName is marked as not modified.
context.Entry(person).Property(p => p.LastName).IsModified = false;
Save changes.
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.
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).
public class PersonModel
{
public int Id { get; set; }
public string FirstName { get; set; }
}
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();
- Create a new Person.
- Set the Id property to 2.
- Create an instance of PersonModel with properties set.
- Attach the new Person which will now be tracked by the change tracker.
- Set the new Person instance values to the properties of the PersonModel.
- 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
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.
Posted on June 13, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.