Entity Framework: An object with the same key already exists in the objectstatemanager

Posted by NealR on Stack Overflow See other posts from Stack Overflow or by NealR
Published on 2013-10-25T15:00:10Z Indexed on 2013/10/25 15:54 UTC
Read the original article Hit count: 132

I see that this question has been asked a lot, however I haven't found anything yet that solves the problem I'm having.

Obviously i'm using the Entity Framework to perform an update to a record. Once the updates are complete, however, whenever I try to save I get the following error message:

An object with the same key already exists in the objectstatemanager

At first I was passing in a collection object from the view that contained a copy of the the ZipCodeTerritory model object zipToUpdate. I changed the code by pulling this object out and just sending in the relevant fields instead. However, I'm still getting the same error.

What's also weird is the first time I run this code, it works fine. Any attempt after that I get the error.

Controller

Here is the code from the method calling the edit function

    public static string DescriptionOnly(ZipCodeIndex updateZip)
    {
        if (!string.IsNullOrWhiteSpace(updateZip.newEffectiveDate) || !string.IsNullOrWhiteSpace(updateZip.newEndDate))
        {
            return "Neither effective or end date can be present if updating Territory Code only; ";
        }

        _updated = 0;

        foreach (var zipCode in updateZip.displayForPaging.Where(x => x.Update))
        {
            ProcessAllChanges(zipCode, updateZip.newTerritory, updateZip.newStateCode, updateZip.newDescription, updateZip.newChannelCode);
        }

        _msg += _updated + " record(s) updated; ";

        return _msg;
    }

And here is the method that actually does the updating.

    private static void ProcessAllChanges(ZipCodeTerritory zipToUpdate, string newTerritory, string newStateCode, string newDescription, 
        string newChannelCode)
    {
        try
        {
            if (!string.IsNullOrWhiteSpace(newTerritory)) zipToUpdate.IndDistrnId = newTerritory;
            if (!string.IsNullOrWhiteSpace(newStateCode)) zipToUpdate.StateCode = newStateCode;
            if (!string.IsNullOrWhiteSpace(newDescription)) zipToUpdate.DrmTerrDesc = newDescription;
            if (!string.IsNullOrWhiteSpace(newChannelCode)) zipToUpdate.ChannelCode = newChannelCode;
            if (zipToUpdate.EndDate == DateTime.MinValue) zipToUpdate.EndDate = DateTime.MaxValue;

            _db.Entry(zipToUpdate).State = EntityState.Modified;
            _db.SaveChanges();
            _updated++;
        }
        catch (DbEntityValidationException dbEx)
        {
            _msg += "Error during update; ";
            EventLog.WriteEntry("Monet", "Error during ProcessAllChanges: " + zipToUpdate.ToString() + " |EX| " + dbEx.Message);
        }
        catch (Exception ex)
        {
            _msg += "Error during update; ";
            EventLog.WriteEntry("Monet", "Error during ProcessAllChanges: " + zipToUpdate.ToString() + " |MESSAGE| " + ex.Message);
        }
    }

EDIT

The ZipCodeIndex object contains a list of ZipCodeTerritory model objects. These aren't being pulled from a linq query, but instead simply passed back to the controller from the view. Here is the signature of the controller method that starts the process:

    [HttpPost]
    public ActionResult Update(ZipCodeIndex updateZip, string button)

© Stack Overflow or respective owner

Related posts about c#

Related posts about .NET