Unable to loop\insert with EF Core cannot be tracked because another instance with the same key value already being tracked

45 views Asked by At

EF Core 2.1, ASP.NET MVC on .NET 4.8.

I have an array being posted up, I just need to simply loop through the items, and insert into the database.

But it keeps throwing this error:

Cannot be tracked because another instance with the same key value for {'Learner Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.

LearnerId is just a plain not null Guid with a FK.

What am I missing here, I've tried just about everything I can think of, I'm going nuts. I probably generally DO WANT tracking for objects, but in this case. I just want it inserted into the database without needing to make a whole stored procedure to do it.

using (var context = new MyContext())
{
    var items = new List<MyItems>();

    foreach (var e in encountersArray)
    {
        items.Add(new MyItem() 
                      {
                          Id = Guid.NewGuid(),
                          LearnerId = learnerId,
                          EncounterId = e,
                          Modified = DateTime.Now
                      });
    }

    context.AddRange(items);
    context.SaveChanges();
}

The Id field even is newid() autogenerated in the database, it's not even required here i'm just trying everything I can think of.

Now it seems to work if I put the new context inside of the foreach so it's disposed after each ADD... but is that at all efficient? I feel like no?

1

There are 1 answers

1
Steve Py On BEST ANSWER

That seems very odd, what entity configuration are you using? Attributes or anything like IEntityTypeConfiguration? I'd check that EF is recognizing "Id" as the PK and not "LearnerId". For instance is the entity class named "MyItem" or "Learner" by chance? If it is "Learner" convention may be picking "LearnerId" as the Key by default. Try explicitly marking "Id" as the PK:

[Key]
public Guid Id { get; protected set; }

The error you are getting implies that it is using LearnerId as the PK for the entity/table.

Typically with PKs it is best to let the database assign the PK value by marking the key as an identity column using [DatabaseGenerated(DatabaseGeneratedOption.Identity)] rather than relying on the code to set a new ID. DB-side you can set the default for the column to NewId() or NewSequentialId(). (SQL Server)