The instance of entity type 'Product' cannot be tracked because another instance with the same key value is already being tracked

Edward picture Edward · Apr 12, 2018 · Viewed 22.2k times · Source

I made a test with code below to update the Product:

var existing = await _productRepository.FirstOrDefaultAsync(c => c.Id == input.Id);
if (existing == null)
    throw new UserFriendlyException(L("ProductNotExist"));
var updatedEntity = ObjectMapper.Map<Product>(input);
var entity = await _productRepository.UpdateAsync(updatedEntity);

But it throws an exception:

Mvc.ExceptionHandling.AbpExceptionFilter - The instance of entity type 'Product' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.

This is caused by querying existing. Is there any solution for this?

Answer

aaron picture aaron · Apr 12, 2018

Since you are not using the existing entity, don't load it.

Use AnyAsync to check if it exists:

var exists = await _productRepository.GetAll().AnyAsync(c => c.Id == input.Id); // Change
if (!exists)                                                                    // this
    throw new UserFriendlyException(L("ProductNotExist"));

var updatedEntity = ObjectMapper.Map<Product>(input);
var entity = await _productRepository.UpdateAsync(updatedEntity);

If you want to map to the existing entity:

var existing = await _productRepository.FirstOrDefaultAsync(c => c.Id == input.Id);
if (existing == null)
    throw new UserFriendlyException(L("ProductNotExist"));

var updatedEntity = ObjectMapper.Map(input, existing); // Change this