Search code examples
c#entity-frameworkaspnetboilerplatechange-trackingasp.net-boilerplate

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


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?


Solution

  • 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