c# - The context is already tracking the entity - I know but how to solve it? - Stack Overflow
The approach that you adopt to modifying entities depends on whether the context is currently tracking the entity being modified or not. The Change Tracker records the current state of an entity using one of four values: the context through one of the following methods of the DbContext It also does this for all reachable entities in the graph that it isn't already tracking. . Entity Framework Core Many To Many Relationships By Convention. Entity Change Tracking using DbContext in Entity Framework 6 . All we have to do now is add the logs to the Context and save the changes.
Attach author ; context. This is useful in scenarios where you are dealing with complex object graphs that consist of various related entities in differing states. The following example replicates a scenario where an object graph is constructed outside of the context. Then the TrackGraph method is used to "walk the graph": SaveChanges ; In this scenario, it is assumed that the author entity has not been changed, but the books might have been edited. The TrackGraph method takes the root entity as an argument, and a lambda specifying the action to perform.
In this case, the root entity, the author has its EntityState set to UnChanged. Setting the EntityState is required for the context to begin tracking the entity. Only then can related entities be discovered. Books have their EntityState set to Modified, which as in the previous examples, will result in SQL that updates every property on the entity: ToString ; if originalValue!
However, we haven't implemented GetPrimaryKeyValue yet. Entity ; return objectStateEntry. Once we have access to that manager, we can get the primary key value note that this method assumes a single-column primary key, which is not necessarily a good real-world scenario, see Drawbacks. Save the Logs All we have to do now is add the logs to the Context and save the changes.
No auditing for Added entities. This is because, in my system, the database is responsible for creating the primary key values via IDENTITY columns and therefore the primary keys do not exist before the entity is added to the database.
Attempting to use the database-generated primary keys for Added entities would result in two round-trips to the database on every save. Support for single-column primary keys only.
This code makes an explicit assumption that only one column per table in your database is the primary key, which is not true in the real world. Summary The method outlined about is a good way to track and audit changes made to existing entities. With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.
Working with Disconnected Entities Including N-Tier Applications In the previous chapter you learned how to add new entities and change or delete existing entities. All the examples we looked at involved making changes one at a time to entities that are tracked by the context.
Each of the changes affected a single entity or relationship. You saw that you can perform multiple of these single entity operations and then call SaveChanges to push all the changes to the database in a single transaction. In this chapter we will look at making changes to entities that are not being tracked by a context. Entities that are not being tracked by a context are known as disconnected entities.
For most single-tier applications, where the user interface and database access layers run in the same application process, you will probably just be performing operations on entities that are being tracked by a context. Operations on disconnected entities are much more common in N-Tier applications.
The Entity Framework Core ChangeTracker
N-Tier applications involve fetching some data on a server and returning it, over the network, to a client machine. The client application then manipulates this data before returning it to the server to be persisted. The N-Tier pattern makes data access more complex because there is no longer a context tracking changes that are made to each entity.
The data is fetched using one context, and returned to the client where there is no context to track changes. The data is then sent back to the server and must be persisted back to the database using a new instance of the context. When it comes time to persist the data on the server, you are typically working with a graph of entities.
A graph of entities is simply a number of entities that reference each other. In the last chapter we looked at adding a relationship using a navigation property, which is enough to create a graph, because one entity now references another. When it comes time to start performing operations on this disconnected graph, there are some additional behaviors in Entity Framework that you need to be aware of. The entity that you perform the operation on is known as the root of the graph.
Performing an operation on the root of disconnected graph can have side effects on the rest of the graph, too. In the previous chapter we saw that DbSet.
Add can be used to register a new entity to be inserted when SaveChanges is called. When an entity is registered with the context it means that the context becomes aware of the entity and starts tracking it. Add essex ; Console. State ; foreach var lodging in essex.
Then the new Destination is added to a context using the Add method. Once the Destination is added, the code uses the DbContext.Managed Object Contexts - Intermediate Core Data - misjon.info
Entry method to get access to the change tracking information that Entity Framework has about the new Destination. From this change tracking information the State property is used to write out the current state of the entity.
Tech Notes: The context is not currently tracking the entity
This process is then repeated for each of the newly created Lodgings that are referenced from the new Destination. If you modify the Main method to call AddSimpleGraph and run the application you will see the following output: Added Big Essex Hotel: Entity Framework also registers these entities as Added and will insert them into the database when SaveChanges is called. The process of finding related entities is recursive, so if one of the new Lodging instances referenced a new Person instance, the Person would also get added to the context.
Adding a disconnected graph of entities If a reference is found to an entity that is already tracked by the context, the entity that is already tracked is left in its current state. For example, if one of our new Lodging instances referenced an existing Person that had been queried for using the context, the existing Person would not be marked as Added.
The existing Person would remain in the Unchanged state and the Lodging would be inserted with its foreign key pointing to the existing Person.
Remember that in an N-Tier application the data is queried for in one context, but the changes need to be persisted using another context. For example, on the server side of your application you could expose a GetDestinationAndLodgings method that will return a Destination with all of its Lodgings: These changes could include changing the Description of the Destination and adding a new Lodging to its Lodgings collection.
The server side of the application could then expose a SaveDestinationAndLodgings method to push all these changes back to the database: The Lodgings property may also contain instances of Lodging that can also be existing or new.
Programming Entity Framework: DbContext by Rowan Miller, Julia Lerman
Your server-side logic could be exposed through a service or perhaps a class that follows the repository pattern. Either way, you need to overcome the disconnected nature of the objects that are returned from the client application. There are a number of different approaches to solving the challenges associated with building N-Tier applications. Using Existing N-Tier Frameworks That Support Graph Modification In a lot of cases you can save yourself the headache of dealing with the intricacies of N-Tier data access by using a framework that takes care of tracking changes that are made to data on the client and applying those changes on the server.
There are frameworks available from other vendors as well. WCF Data Services allows you to choose what data from your model is exposed from the server and what permission clients have for the data read, append, update, and so on.
WCF Data Services also includes a client component that takes care of tracking changes you make to data on the client, pushing those changes back to the database, and saving them using your Entity Framework model.
WCF Data Services is a good option for building N-Tier applications, but there are some reasons it may not be the right tool for your job. WCF Data Services gives you quite a bit of control over how requests are processed on the server, but it is a framework and therefore it is somewhat scoped in what it can handle.
Depending on your application, you may have some advanced requirements that are not supported. In these situations, authoring your own web services may be the only viable option.
This replaced the default code generation with a template that produced entities that would internally track their changes on the client and transfer the information back to the server. The template also generated some helper methods that would take the change tracking information and replay the changes back into a context on the server. They are recommending that developers look at using WCF Data Services as a more robust and complete solution.
Using Explicit Operations on the Server Side Another way to avoid the complexity of determining the changes to be made on the server is to expose very granular operations that require the client to identify the exact change to be made. For example, rather than the SaveDestinationAndLodgings method we saw earlier in this chapter, you could expose AddDestination and UpdateDestination methods.
These methods would only operate on a standalone Destination instance rather than a graph of entities. You would expose separate methods for adding and updating Locations.