Share via


Entity Framework FAQ: ObjectContext

   

It depends on the scenario.  For single-threaded rich-client applications, sharing a global ObjectContext may make sense--it may even provide advantages since identity resolution will reduce the number of in-memory objects as they are re-used across queries.  You do, however, need to carefully manage the memory consumption of your application, because the ObjectContext will maintain a reference to every entity retrieved through it unless you use a NoTracking query or explicitly detach it. For more information, see Managing Resources in Object Services (Entity Framework).

For ASP.NET and web service applications, we recommend that you do NOT share a single global ObjectContext for a number of reasons, including threading issues (ObjectContext is not thread-safe), working set (because the context keeps references to objects retrieved through it as mentioned above), and data consistency (as the data in the database evolves over time it can get out of sync with the data in your local objects unless you explicitly query with an OverwriteChanges MergeOption).  From http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2371610&SiteID=1

It should also be noted that it is possible to share a single ObjectContext across multiple EntityDataSource instances on an ASP.NET page.  This should be managed carefully to avoid conflicts between the actions of the data sources, but it can provide some performance benefit.  For more information, see Object Context Life-Cycle Management (EntityDataSource).  Also, see the Object Context section of the Working with Objects topic.

 

What is the recommendation for running a multithreaded application on the Entity Framework?  Is the Entity Framework thread-safe?

The Entity Framework, like most of the rest of the .NET framework, is by and large NOT thread-safe. So if you want to interact with the Entity Framework or your entity classes from multiple threads, then you must pay careful attention to concurrency issues.  One simple model that works for some cases is for each thread to maintain its own context so that no locking is required. This means, of course, that the interactions between the threads must be quite limited (for instance you can't pass an entity from one thread to another without being very careful), but you can do some useful things in spite of these restriction. You could, for example, retrieve data on one thread by using `MergeOption.NoTracking`, and then divide the data into groups and hand it off to other threads that attach the entities to their own thread context, make updates, and then save.

You could also have one thread for all of your database interactions and send entities over to other threads for processing and back to the database thread for a save. In this scenario, make sure the entities are detached from the context any time they are updated on the other threads or else you will end up with race conditions as the state manager works to keep track of all those changes and therefore is implicitly used from multiple threads simultaneously.

 

Does the provider connection stay open for the entire lifetime of the Object Context?  When is the provider connection opened/closed?

The Object Context keeps the connection closed as much as possible while still appropriately dealing with transactions and avoiding promotion of those transactions from local to DTC where possible. The Object Context does NOT keep the connection open from the time ObjectContext was constructed through the life of the context because this would create issues, for instance, with databases where licensing is based on the number of concurrently open connections, because the connection might be held open for an extended period of time even when it is not being used.

You can also exercise more explicit control over the connection by manually opening or closing it.  If you open the connection, the context will leave it open until you explicitly close it or the context is disposed. For more information, see Managing Connections (Entity Framework).

 

Do I need to explicitly call Dispose() on the ObjectContext object after use?

No, you don't have to, but you should...

ObjectContext holds state (for example, a SqlConnection and pointers to the objects you have retrieved). These will eventually get cleaned up by the garbage collector (GC) after you release all references, but some of these objects (for example, the underlying SqlConnection) may be holding resources that you typically want to release as soon as you are finished, rather than relying on the GC to clean up.

It is recommended that you construct an ObjectContext within a using statement to make sure that resources are cleaned up when you leave the block.  For example, in C# you would do something like this:

 using (NorthwindObjectContext db = new NorthwindObjectContext())
 {
   // do stuff with ObjectContext 
 } // Dispose is called on ObjectContext when you leave the using block

This is the same pattern as what is recommended for using DbConnections in ADO.NET 2.0. For more information, see Managing Resources (Entity Framework).  From <http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2354870&SiteID=1>

 

What is the ObjectContext.Detach() method used for?

ObjectContext.Detach() detaches an object from the ObjectStateManager associated with an object context so that the state manager does not maintain any references to the object and (in the case of objects inheriting from EntityObject or implementing IObjectWithChangeTracker) the object maintains no references back to the state manager.  This allows the object to be reclaimed by the garbage collector, and for objects implementing IObjectWithChangeTracker it allows them to be attached to a different context. (POCO objects can be attached to more than one context at a time, but those that implement IEntityWithChangeTracker typically cannot.)  For more information, see Detaching Objects (Entity Framework).