0
votes

I have this Controller action:

[HttpGet]
[Route("api/person/test/{id}")]
public IHttpActionResult Test(Guid id)
{
    var person = this.PersonManager.Get(id);

    person.Lastname = "Jameson";

    this.PersonManager.Save(person);

    return Ok(true);
}

Deep underneath this save method is called:

protected void Add<T>(T source, MyEntities context, bool isNew) where T : class
{
    if (isNew)
    {
        context.Set<T>().Add(source);
    }
    else
    {
        var entry = context.Entry(source);
        if (entry.State == EntityState.Detached)
        {
            context.Set<T>().Attach(source);

            entry.State = EntityState.Modified;
        }
    }
}

I get this error when executing this:

Attaching an entity of type 'Model.Person' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.

It occurs on the context.Set<T>().Attach(source) line.

PS: This is a followup/spin off of this question.

1
Why is your entity detached in this case, if you load it using Get? Looks like it's loaded and kept in DbContext, so when you attach it again it conflicts with original copy of itself. Also do you dispose context between Get and Save operations?Red
@raderick: Good question. The question this is a followup off was regarding an unexpected Dispose. It may be the cause of this issue.Spikee
you should definitely track entity state of your person entity from loading to saving again, looks like at some point it's detached but also kept in the same context, so when you attach it again this issue happens.Red
can you check context.person.Local to see if have one person object which have the same primary with the updated person object?Shawn

1 Answers

0
votes

try this

if (!context.Set<T>().Local.Contains(source))
 {
    context.Set<T>().Attach(source);
 }

context.Entry(source).State = EntityState.Modified;