简体   繁体   中英

Entity Framework core - The instance of entity type cannot be tracked because another instance of this type with the same key is already being tracked

Am currently trying out my hand in .net core and EF core.

I have the following code to update the data

protected void Update(T entity, bool saveChanges = true)
{
    _context.Set<T>().Attach(entity);
    _context.Entry(entity).State = EntityState.Modified;
    if (saveChanges) _context.SaveChanges();
}

The class I am updating

public partial class Blog
{
    public Blog()
    {
        Post = new HashSet<Post>();
    }

    public int BlogId { get; set; }
    public string Url { get; set; }

    public virtual ICollection<Post> Post { get; set; }
}

When I try to update any entry the first time, it is successful. The second time I update the same entry, I get the below error:

System.InvalidOperationException: 'The instance of entity type 'Blog' cannot be tracked because another instance of this type with the same key is already being tracked. When adding new entities, for most key types a unique temporary key value will be created if no key is set (ie if the key property is assigned the default value for its type). If you are explicitly setting key values for new entities, ensure they do not collide with existing entities or temporary values generated for other new entities. When attaching existing entities, ensure that only one entity instance with a given key value is attached to the context.'

The same occurs for each entry, successful for the first time and fails the second time.

Additional Information: I get all the data using the below code:

protected IEnumerable<T> GetAll()
{
    return _context.Set<T>().AsNoTracking().AsEnumerable();
}

Display the above as a table in the view. DTO's are being used to communicate between the data and web layer.

The context is registered in startup as below

services.AddDbContext<BloggingContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

My question is why there is an error during the second update and how to resolve it. Thanks.

Your Service Provider is static and so it is a singleton in fact. As suggested here github.com/aspnet/EntityFramework/issues/2652

that exception means that you are trying to attach two entity instances that have the same key to a context. This occurs when a singleton instance of a repository is injected at startup.

I d suggest to change your generic Repository from an abstract class to an interface , and inject the proper repositories during the Startup:

services.AddScoped<IRepository<Blog>, BlogRepository>();
services.AddScoped<IRepository<Post>, PostRepository>();

instead of your static ServiceProvider which actually provides a singleton implementation of your BlogRepository

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM