Efcore: Additional information: The instance of entity type ... cannot be tracked because another instance of this type with the same key is already being tracked. For new entities consider using an IIdentityGenerator to generate unique key values.

Created on 22 Nov 2015  Â·  5Comments  Â·  Source: dotnet/efcore

I have a generic repository implemented in a class library all CRUD methods except works _dbSet.Remove(entity);

The instance of the object is defined as AddScope.

Could someone help me

An exception of type 'System.InvalidOperationException' occurred in EntityFramework.Core.dll but was not handled in user code

Additional information: The instance of entity type 'TMS.Domain.Entities.Pais' cannot be tracked because another instance of this type with the same key is already being tracked. For new entities consider using an IIdentityGenerator to generate unique key values.

public class RepositoryBase<TEntity> : IRepositoryBase<TEntity> where TEntity : class
{

    private IAppDbContext _dbContext;
    protected DbSet<TEntity> _dbSet;


    public RepositoryBase(IAppDbContext dbContext)
    {
        _dbContext = dbContext;
        _dbSet = _dbContext.Set<TEntity>();
    }

    //public RepositoryBase()
    //{
    //    _dbContext = new AppDbContext();
    //    _dbSet = _dbContext.Set<TEntity>();
    //}

    public virtual IEnumerable<TEntity> GetAll()
    {
        return _dbSet.ToList();
    }

    public IEnumerable<TEntity> GetAllAsReadOnly()
    {
        return _dbSet.AsNoTracking();
    }

    public virtual IEnumerable<TEntity> GetBy(Expression<Func<TEntity, bool>> filter)
    {
        return _dbSet.Where(filter);
    }

    public IQueryable<TEntity> GetQueryBy(Expression<Func<TEntity, bool>> filter)
    {
        return _dbSet.Where(filter);
    }

    public virtual void Create(TEntity entity)
    {
        _dbSet.Add(entity);
    }

    public virtual void Edit(TEntity entity)
    {
        _dbSet.Update(entity);
    }

    public virtual void Delete(TEntity entity)
    {
        _dbSet.Remove(entity);
    }

    public int Save()
    {
        return _dbContext.SaveChanges();
    }

    public void Dispose()
    {
        //_dbContext.Dispose();
        GC.SuppressFinalize(this);
    }

    public TEntity FindBy(Expression<Func<TEntity, bool>> filter)
    {
        return _dbSet.Where(filter).SingleOrDefault();
    }

    public TEntity FindAsReadOnlyBy(Expression<Func<TEntity, bool>> filter)
    {
        return _dbSet.Where(filter).AsNoTracking().SingleOrDefault();
    }

    public void Delete(Expression<Func<TEntity, bool>> filter)
    {
        TEntity entity = _dbSet.Where(filter).SingleOrDefault();
        _dbSet.Remove(entity);
    }
}

Most helpful comment

It worked perfect with AsNoTracking ();

Thank you!

All 5 comments

as the error suggests, it sounds like your context instance already has an Addon with the same primary key value as one that you are trying to query/add/etc. Can you post the full stack trace?

This is the stack:

InvalidOperationException: The instance of entity type 'TMS.Domain.Entities.Pais' cannot be tracked because another instance of this type with the same key is already being tracked. For new entities consider using an IIdentityGenerator to generate unique key values.
em Microsoft.Data.Entity.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry)
em Microsoft.Data.Entity.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges)
em Microsoft.Data.Entity.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges)
em Microsoft.Data.Entity.ChangeTracking.EntityEntry.set_State(EntityState value)
em Microsoft.Data.Entity.DbContext.Remove[TEntity](TEntity entity)
em Microsoft.Data.Entity.Internal.InternalDbSet`1.Remove(TEntity entity)
em TMS.Infra.Data.Repositories.RepositoryBase`1.Delete(TEntity entity) na C:\Demo\src\TMS.Infra.Data\Repositories\RepositoryBase.cs:linha 56
em TMS.Domain.Services.ServiceBase`1.Delete(TEntity entity) na C:\Demo\src\TMS.Domain\Services\ServiceBase.cs:linha 52
em TMS.Domain.Services.PaisService.DeleteValidation(Pais pais) na C:\Demo\src\TMS.Domain\Services\PaisService.cs:linha 35
em TMS.Application.AppService.PaisAppService.DeleteValidation(PaisViewModel paisViewModel) na C:\Demo\src\TMS.Application\AppService\PaisAppService.cs:linha 28
em TMS.Web.Controllers.PaisesController.DeleteConfirmed(Int32 id) na C:\Demo\src\TMS.Web\Controllers\PaisesController.cs:linha 143
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
em Microsoft.AspNet.Mvc.Controllers.ControllerActionExecutor.ExecuteAsync(MethodInfo actionMethodInfo, Object instance, Object[] orderedActionArguments)
em Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker.<InvokeActionAsync>d__6.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
em System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
em Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.<InvokeActionFilterAsync>d__53.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
em Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.<InvokeAsync>d__44.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.GetResult()
em Microsoft.AspNet.Mvc.Infrastructure.MvcRouteHandler.<RouteAsync>d__6.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.GetResult()
em Microsoft.AspNet.Routing.Template.TemplateRoute.<RouteAsync>d__27.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.GetResult()
em Microsoft.AspNet.Routing.RouteCollection.<RouteAsync>d__9.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.GetResult()
em Microsoft.AspNet.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.GetResult()
em Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
em Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.GetResult()
em Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
em Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.GetResult()
em Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
em Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.GetResult()
em Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
em Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.GetResult()
em Microsoft.AspNet.IISPlatformHandler.IISPlatformHandlerMiddleware.<Invoke>d__8.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.GetResult()
em Microsoft.AspNet.Diagnostics.Entity.MigrationsEndPointMiddleware.<Invoke>d__5.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.GetResult()
em Microsoft.AspNet.Diagnostics.Entity.DatabaseErrorPageMiddleware.<Invoke>d__6.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
em Microsoft.AspNet.Diagnostics.Entity.DatabaseErrorPageMiddleware.<Invoke>d__6.MoveNext()
--- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
em System.Runtime.CompilerServices.TaskAwaiter.GetResult()
em Microsoft.AspNet.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()

Currently own a project that dry this architecture wanted to migrate but without making major modifications.

An example of this design is that the error to delete an entity.

https://github.com/gilmaremn/EF7Demo

Hey,

Looking at your code, I think it's these lines of code in PaisesController.cs that are causing your issue...

c# 141 PaisViewModel paisViewModel = _paisApp.GetBy(id).SingleOrDefault(); 142 143 ValidationResultApp result = _paisApp.DeleteValidation(paisViewModel);

The "query for an instance and then mark as deleted" pattern you are doing is good, the problem is that because of the various layers of abstraction you don't end up marking the actual entity instance as deleted, you attempt to tell the context that a new instance of the entity is deleted... but it has the same primary key value that was created when you queried for the entity from the database.

There are two options here:

  • Update the repository to lookup the existing entity (based on the key values of the entity passed to the Delete method) and mark it as deleted.
  • Use the AsNoTracking() method whenever you retrieve data, this avoids having the entities be tracked by the context and frees you up to re-attach new instances when you want to update/delete.

It worked perfect with AsNoTracking ();

Thank you!

Was this page helpful?
0 / 5 - 0 ratings