Entities created outside of a DbContext, or loaded from a different DbContext that has gone out of scope, must be attached to a DbContext before EF can persist changes to the underlying data store. This section covers how the entity operations—Add, Update, and Remove—attach entities as well as the special Attach command. The state that gets assigned to an entity when attached depends on the command used and the values of the primary key or keys.
- [Instructor] In the section on tracking versus no-tracking queries, I mentioned the potential performance improvement when you use untracked entities. And web applications typically work with detached entities. You create a context, you return the requested data to the user and that context goes away. At some point in time, the user might submit changes back to the server, where model binding, if you're using ASP.NET Core, will then reconstitute an object.
This object is not attached to any context. So then, you can attach it to the DbContext using Attach, Add, Update or Remove on the DbContext. We saw this in action earlier. You can also specifically detach an entity from a DbContext by setting the entity state to detached. As I mentioned when we were talking about entity operations, the entity state after an Attach operation can vary based on the method used and the primary key types and values.
So if your entity is missing, or has default primary key values, then when you Attach, Add, or Update, it will be set to the added state. Remove will actually throw an exception, because you are calling Remove on an unattached or detached entity and there's no primary key, so entity framework does not know what to do. If the entity has assigned primary key values, then when you do an Attach, it will be in the unchanged state.
If you call Add, it'll be in the added state. Update will then set it to the modified state, and Remove will set it to deleted. You can use entity state to affect changes to data without having to load the entity from the data store. For example, if your web application has a page that allows for deletion of an object, there is no benefit to retrieving that object into the change tracker just to remove it. You can simply call remove on the reconstituted entity, having any primary key and concurrency values set on the object.
So the process is very simple. You create a new entity instance. You assign the appropriate values. At the minimum, those are the primary key values, or value if it's a single primary key. You attach it to the context, and you call SaveChanges. Now, it's a minimum of those values if you're doing a Delete. If you're doing an Update, then you're going to want to update all appropriate properties. There is a catch, and it's not a big deal, it's very easy to check for, but the entity cannot already be tracked by the ChangeTracker.
The ChangeTracker will only accept one instance of an entity for primary key.
- 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