The Entity Framework Core Change Tracker uses EntityState to determine what operations need to be executed when SaveChanges is called. This section discusses the effect that entity operations have on the value of EntityState. Phil also covers the SaveChanges method and its effect on EntityState.
- [Instructor] An entity state determines what operation needs to be done to persist the data to the database. The ChangeTracker, as we've discussed before, tracks those changes to the entities in the DbContext. And each tracked entity's state is either Added, Modified, Deleted, or Unchanged. Then untracked entities have a state set to Detached. So how do we get those states set? Well there's a series of entity operations, Add, Update, and Remove.
Each of those has a range version, such as AddRange, UpdateRange, RemoveRange, which operates on a list of entities, and they all have async versions as well. So Add will add an entity into the DbSet, sets it to be tracked, and sets the entity state to Added. The Update operations add the entities into the DbSet, starts tracking them, and will either set the state to Modified or Added.
If the primary key values are existent, it will be considered to be Modified, and if they do not have primary key values, it will be considered to be Added. We'll cover that a lot more in the Detached Entities section coming up soon. And then the Remove operations sets the state to Deleted. The Add, Update, and Remove don't actually make a call to the database, and that's done through SaveChanges, which we'll talk about shortly. So why are there async versions? Well there are some special conditions where the database access is required for special value generation such as the high low sequence ID available with SQL server.
If you are not using one of those special cases, then you should always use the nonasync versions. And then there's another operation, Attach or AttachRange, and this operation attaches untracked entities to the DbSet. And we'll cover that in more detail again in the Detached Untracked Entities section coming up. So now that we have the entities in a DbSet, this ChangeTracker is tracking them and their state.
To persist the changes, we call SaveChanges. The DbContext.SaveChanges method invokes the database provider to create the proper syntax to persist the changes. So for the SQL server provider, that will be T-SQL. And then it will create the specific Insert, Update, and Delete statements. A successful save operation resets all entity states to Unchanged, although you can disable that and then set them yourselves.
And as mentioned before, it will be covered again in great detail in the next section. SaveChanges operates as an implicit transaction. EF Core also supports asynchronous saves, and that's just by calling SaveChangesAsync. And all the same rules apply as when we talked about async queries. EF Core doesn't support multiple open operations on a context, so you should always await the async operations.
And remember, calling it with an async method doesn't make the query or the updates any faster, it just means your program is potentially more responsive.
- Persisting data
- Tracking EntityState
- Configuring the DbContext
- Transactions across DbContexts
- Understanding the batching process
- Attaching and deleting detached entities
- Design time configuration
- Concurrency checking
- Using custom execution strategies