Search code examples
c#entity-frameworkentity-framework-core.net-core-3.1

The instance of entity type cannot be tracked because another instance with the same key value is already being tracked


I'm getting a same key value runtime exception from entity base class. I tried few online solutions with no lucks. Can anyone help me to fix this issue? Following line throwing Exception when I try to update:

this.RepositoryContext.Set().Update(entity);

Framework : .netcore 3.1

Error:

{"The instance of entity type 'JobConnection' cannot be tracked because another instance with the same key value for {'JobConnectionId'} is already being tracked. 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."}.

Here is the call:

public void UpdateJobConn(JobConnection jobfile)
        {
            Update(jobfile);
            Save();
        }

Here is the whole Repository class:

using Foreside.Etp.Contracts;
using Foreside.Etp.Entities.Models;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Linq;

namespace Foreside.Etp.Repository
{
    public abstract class RepositoryBase<T> : IRepositoryBase<T> where T : class
    {
        protected EtpRepoContext RepositoryContext { get; set; }

        public RepositoryBase(EtpRepoContext repositoryContext)
        {
            this.RepositoryContext = repositoryContext;
        }

        public IEnumerable<T> FindAll()
        {
            return this.RepositoryContext.Set<T>();
        }

        public IEnumerable<T> FindByCondition(Expression<Func<T, bool>> expression)
        {
            return this.RepositoryContext.Set<T>().Where(expression);
        }

        public void Create(T entity)
        {
            this.RepositoryContext.Set<T>().Add(entity);
        }

        public void Update(T entity)
        {
            this.RepositoryContext.Set<T>().Update(entity);
        }

        public void Delete(T entity)
        {
            this.RepositoryContext.Set<T>().Remove(entity);
        }

        public void Save()
        {
            this.RepositoryContext.SaveChanges();
        }
    }
}

JobConnection Model -

public partial class JobConnection
    {
        public int JobConnectionId { get; set; }
        public int KeyId { get; set; }
        public int ConnectionId { get; set; }
        public string Directory { get; set; }
        public int JobId { get; set; }
        public int ConnectiontypeId { get; set; }
    }

Context -

 public virtual DbSet<JobConnection> JobConnection { get; set; }

modelBuilder.Entity<JobConnection>(entity =>
        {
            entity.ToTable("job_connection");

            entity.HasKey(e => e.JobConnectionId);

            entity.Property(e => e.JobConnectionId)
                .HasColumnName("jobconnectionid")
                .HasColumnType("int(11)");

            entity.Property(e => e.ConnectionId)
                .HasColumnName("connectionid")
                .HasColumnType("int(11)")
                .HasDefaultValueSql("0");

            entity.Property(e => e.ConnectiontypeId)
                .HasColumnName("connectiontypeid")
                .HasColumnType("int(11)");

            entity.Property(e => e.Directory)
                .IsRequired()
                .HasColumnName("directory")
                .HasMaxLength(50)
                .IsUnicode(false)
                .HasDefaultValueSql("0");

            entity.Property(e => e.JobId)
                .HasColumnName("jobid")
                .HasColumnType("int(11)");

            entity.Property(e => e.KeyId)
                .HasColumnName("keyid")
                .HasColumnType("int(11)")
                .HasDefaultValueSql("0");
        });

Table -

SHOW INDEXES
FROM job_connection

job_connection  0   PRIMARY 1   jobconnectionid A   63              BTREE       

Solution

  • Finally I fixed this issue by detaching the EntityState. I really appreciate for sharing your thoughts - it helped to think it through. Please find the problem and the correct solution below.

    Problem :

    There was at least an orphan tracked instance preventing from working with the correct instance that I want to update in DB - basically this is a duplicate instance which was interfering when context was trying to update in DB and were not able to save any references for JobConnection. Context was somehow storing references on inserted objects even after leaving scope of their declaration and initialization.

    Solution:

    There could be multiple ways to solve this issue. One of the ways is to detach the instance from context in order to avoid similar orphaned duplicate instances which was causing issues for our case. Here is an example how I fixed in code :

    _context.Entry<JobConnection>(jobCon).State = EntityState.Detached;  //Explicitly Detach the orphan tracked instance 
    

    Another example in code that has similar issue and here is the solution.

    var inFiles = _filerepository.FindAllInboundFilesByJobId(job.Jobid);
    foreach (File inFile in inFiles)
    _context.Entry<File>(inFile).State = EntityState.Detached;