Entity framework Core - The instance of entity type cannot be tracked because another instance with the key value is already being tracked

asp.net-core c# entity-framework-core

Question

Trying to establish a many to many relationship in my db context, I got the following error while seeding data:

The instance of entity type 'Folder' cannot be tracked because another instance with the key value '{Id: folder001 }' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);
    builder.Entity<UserFolder>(userFolder =>
    {
        userFolder.HasKey(ud => new { ud.UserId, ud.FolderId });

        userFolder.HasOne(uf => uf.Folder)
            .WithMany(f => f.Users)
            .HasForeignKey(uf => uf.FolderId)
            .IsRequired();

        userFolder.HasOne(uf => uf.User)
            .WithMany(f => f.Folders)
            .HasForeignKey(uf => uf.UserId)
            .IsRequired();
    });
}

_

public class Folder
{

    public string Id { get; set; }
    public string FolderName { get; set; }

    public virtual ICollection<UserFolder> Users { get; set; }
}

_

public class User
{

    public string Id { get; set; }
    public string UserName { get; set; }

    public virtual ICollection<UserFolder> Folders { get; set; }
}

_

public class UserFolder
{
    public string UserId { get; set; }
    public virtual User User { get; set; }

    public string FolderId { get; set; }
    public virtual Folder Folder { get; set; }

}

Searching this error results mostly to answers talking about the need to use Scoped instead of Singleton to register the service, but here I am configuring my service this way: services.AddDbContext<DataContext>, also some answers say that it is needed to add .AsNoTracking().

So how can I get rid of this error ?

1
0
1/30/2020 12:34:18 AM

Accepted Answer

You have not actually posted the code that is relevant to the error, but I can explain the cause of the error.

Entity Framework has a changetracker, which means that a db context has a sort of "secret dictionary" of entities it knows about, which it uses like a cache to cut down on database calls and keep track of what you do and don't change about these entities. These entities are stored and referenced in the change tracker using their primary key.

Entity Framework can only store one object of a given type and a given PK value. It cannot track two distinct object that have the same value.

Think of it as if it were a dictionary, which can only store one value for a given key value. A dictionary happily overwrites one values with another, but EF instead refuses to do so as this is so very likely to lead to unexpected behavior and hard to troubleshoot bugs.

The following code will throw the same error as you're experiencing:

using(var db = new MyContext())
{
    Foo foo1 = new Foo() { Id = 123 };
    Foo foo2 = new Foo() { Id = 123 }; // different object in memory, same PK identifier

    db.Foos.Attach(foo1);
    db.Foos.Attach(foo2); // exception! 
}

I cannot tell you where in your code this error is being caused since you did not post the code in which this is may be happening.

1
1/29/2020 11:31:04 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow