C # Entity Framework using only one ObjectContext for HttpContext

In ASP.NET MVC 2, using Entity Framework 4, I get this error "An entity object cannot reference multiple instances of IEntityChangeTracker."

A SO search shows that, probably because I have different ObjectContext instances of the Entity Framework object, when it should be only one ObjectContext instance for each HttpContext.

I have this code (written long before I joined) that seems to do just that - it has one ObjectContext for each HttpContext. But I often get an "IEntityChangeTracker" exception, so it probably doesn't work as intended:

// in ObjectContextManager.cs public const string ConnectionString = "name=MyAppEntities"; public const string ContainerName = "MyAppEntities"; public static ObjectContext GetObjectContext() { ObjectContext objectContext = GetCurrentObjectContext(); if (objectContext == null) // create and store the object context { objectContext = new ObjectContext(ConnectionString, ContainerName); objectContext.ContextOptions.LazyLoadingEnabled = true; StoreCurrentObjectContext(objectContext); } return objectContext; } private static void StoreCurrentObjectContext(ObjectContext objectContext) { if (HttpContext.Current.Items.Contains("EF.ObjectContext")) HttpContext.Current.Items["EF.ObjectContext"] = objectContext; else HttpContext.Current.Items.Add("EF.ObjectContext", objectContext); } private static ObjectContext GetCurrentObjectContext() { ObjectContext objectContext = null; if (HttpContext.Current.Items.Contains("EF.ObjectContext") objectContext = (ObjectContext)HttpContext.Current.Items["EF.ObjectContext"]; return objectContext; } 

I have studied this code and it looks right. It, as far as I can tell, returns one instance of ObjectContext for each HttpContext. Is the code incorrect?

If the code is not incorrect, why else do I get: "An entity object cannot reference multiple instances of an IEntityChangeTracker exception?

EDIT: show how ObjectContext is placed:

 // in HttpRequestModule.cs private void Application_EndRequest(object source, EventArgs e) { ServiceLocator.Current.GetInstance<IRepositoryContext>().Terminate(); } // in RepositoryContext.cs public void Terminate() { ObjectContextManager.RemoveCurrentObjectContext(); } // in ObjectContextManager.cs public static void RemoveCurrentObjectContext() { ObjectContext objectContext = GetCurrentObjectContext(); if (objectContext != null) { HttpContext.Current.Items.Remove("EF.ObjectContext"); objectContext.Dispose(); } } 
+5
source share
1 answer

I assume that you saved the object somewhere in memory (most likely, the cache http file using in-process mode, but it can also be any manual cache, such as a common dictionary), and now you somehow linked this object with something else like:

 newOrder.OwnerUser = currentUser; // <== let say currentUser came from cache // and newOrder was on your new entity context 

Therefore, the problem is if the cached object still considers it to be context bound; Last but not least, you probably accidentally save the entire schedule.


The code looks fine (as long as you delete it at the end of the request), but this would be a good time to add:

 private const string EFContextKey = "EF.ObjectContext"; 

and use this instead of 5 literals. Avoids multiple risks; p

+5
source

Source: https://habr.com/ru/post/892741/


All Articles