Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 499
Edward Avatar asked Apr 12 '18 13:04

Edward


People also ask

When attaching existing entities ensure that only one entity instance with a given key value is attached consider using?

When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder. EnableSensitiveDataLogging' to see the conflicting key values.

What difference does AsNoTracking () make?

AsNoTracking(IQueryable)Returns a new query where the entities returned will not be cached in the DbContext or ObjectContext. This method works by calling the AsNoTracking method of the underlying query object.

What is EntityState detached?

Detached. 1. The object exists but is not being tracked. An entity is in this state immediately after it has been created and before it is added to the object context.

What is EntityState modified?

EntityState.Added : EntityState.Modified; context.SaveChanges(); } } Note that when you change the state to Modified all the properties of the entity will be marked as modified and all the property values will be sent to the database when SaveChanges is called.


2 Answers

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
like image 171
aaron Avatar answered Sep 18 '22 18:09

aaron


AsNoTracking() could help you.

like image 30
Yaina Villafañes Avatar answered Sep 22 '22 18:09

Yaina Villafañes