An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key
Solution 1:
If you load the entity from the context you cannot attach an entity with the same key again. The first entity is still kept in internal context cache and context can hold only one instance with given key value per type (it is called identity map and I described it here in other situation).
You can solve it by detaching former instance but you don't have to. If you only need to save new values you can use this:
- ObjectContext API:
context.YourEntitySet.ApplyCurrentValues(newEntity);
- DbContext API:
context.Entry(oldEntity).CurrentValues.SetValues(newEntity);
Solution 2:
Just a bit of help for you if you don't know how to find the oldEntity
as according to Ladislav:
var entityKey = context.NewEntitySet.Create().GetType().GetProperty("Id").GetValue(newEntity);
factory.Entry(context.Set<NewEntityType>().Find(entityKey)).CurrentValues.SetValues(newEntity);
Solution 3:
As the error clearly states - you need to make sure to get existing item and modify that item data with updated information and save it. You will not run into this issue if you update very specific information and not key information such as ID and ForeignKey ID
Below code should do the job!
public virtual void Update(TEntity entity)
{
_context.Entry(entity).State = EntityState.Modified;
this._context.SaveChanges();
}
Usage will be -
public async Task<bool> UpdateVendorItem(string userId, Vendor modified)
{
try
{
var existing = await this.GetVendors().SingleOrDefaultAsync(a => a.Id == modified.Id);
//Set updated info
existing.VendorName = modified.VendorName;
//Update address information
existing.Address.AddressLine1 = modified.Address.AddressLine1;
...
await _vendorRepository.UpdateAsync(existing);
...