An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key

Entity Frameworkasp.net Mvc-3

Entity Framework Problem Overview


I have following code to add or update the Entity object. finding the object by primary key, based on the response I am adding or updating the object.

Adding record works, but during update its giving this error message "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key"

In my MSSQL database I have only one record.

var v = db.Envelopes.Find(model.ReportDate, model.Service);
if (v == null)
{
    db.Envelopes.Add(model);
    db.SaveChanges();
    ViewBag.status = "Record Add successfully";
    ModelState.Clear();
}
else
{
    db.Entry(model).State = EntityState.Modified;
    db.SaveChanges();
}

How can I fix this error message?

Entity Framework Solutions


Solution 1 - Entity Framework

As mentioned by @anon you can't attach model once you loaded the entity with the same key. The changes must be applied to attached entity. Instead of this:

db.Entry(model).State = EntityState.Modified;

use this:

db.Entry(v).CurrentValues.SetValues(model);

Solution 2 - Entity Framework

If an earlier query read the entity to be updated and that's why you're getting the error, you can change that query to AsNoTracking. See the AsNoTracking example in: http://www.asp.net/entity-framework/tutorials/advanced-entity-framework-scenarios-for-an-mvc-web-application

Solution 3 - Entity Framework

I assume you are saying that your error occurs here:

db.Entry(model).State = EntityState.Modified;

Once you execute Find(), your Envelope is already being tracked by your context. This means that if you need to change a property, just change it on v, and then call SaveChanges(). Don't worry about setting the state to Modified.

Solution 4 - Entity Framework

If you set your context to AsNoTracking() this will stop aspmvc tracking the changes to the entity in memory (which is what you want anyway on the web). Don't forget the using statement.

using System.Data.Entity;

db.Envelopes.AsNoTracking().Find(model.ReportDate, model.Service);

I got this from this forum post -> http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application

Solution 5 - Entity Framework

I'm using this because I have already created a new instance, and populated the properties I need to update.

var key=this.CreateEntityKey("Envelopes",model); 
		ObjectStateEntry ose;
		if(this.ObjectStateManager.TryGetObjectStateEntry(key, out ose)){
			var entity=(Page)ose.Entity;
			Envelopes.Detach(entity);
		}
            this.Envelopes.Attach(model);

Solution 6 - Entity Framework

And another approach to solve the issue is detaching tracked entity and re-attaching the modified one. See my solution here.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsfgroupsView Question on Stackoverflow
Solution 1 - Entity FrameworkLadislav MrnkaView Answer on Stackoverflow
Solution 2 - Entity FrameworktdykstraView Answer on Stackoverflow
Solution 3 - Entity FrameworkanonView Answer on Stackoverflow
Solution 4 - Entity FrameworkDavid SwindellsView Answer on Stackoverflow
Solution 5 - Entity FrameworkMaslowView Answer on Stackoverflow
Solution 6 - Entity FrameworkAlexander ChristovView Answer on Stackoverflow