无法跟踪实体类型的实例,因为已在跟踪具有相同键值的另一个实例

Par*_*tha 9 c# entity-framework entity-framework-core .net-core-3.1

我从实体基类得到相同的键值运行时异常。我尝试了一些在线解决方案,但没有成功。谁能帮我解决这个问题?当我尝试更新时,以下行抛出异常:

this.RepositoryContext.Set().Update(实体);

框架:.netcore 3.1

错误:

{“无法跟踪实体类型“JobConnection”的实例,因为已跟踪具有相同 {'JobConnectionId'} 键值的另一个实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例.考虑使用“DbContextOptionsBuilder.EnableSensitiveDataLogging”来查看冲突的键值。”}。

这是调用:

public void UpdateJobConn(JobConnection jobfile)
        {
            Update(jobfile);
            Save();
        }
Run Code Online (Sandbox Code Playgroud)

这是整个 Repository 类:

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

工作连接模型 -

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; }
    }
Run Code Online (Sandbox Code Playgroud)

语境 -

 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");
        });
Run Code Online (Sandbox Code Playgroud)

桌子 -

SHOW INDEXES
FROM job_connection

job_connection  0   PRIMARY 1   jobconnectionid A   63              BTREE       
Run Code Online (Sandbox Code Playgroud)

Par*_*tha 9

最后我通过分离 EntityState 解决了这个问题。我真的很感谢分享你的想法——这有助于我彻底思考。请在下面找到问题和正确的解决方案。

问题 :

至少有一个孤立的跟踪实例无法使用我想要在数据库中更新的正确实例 - 基本上这是一个重复的实例,当上下文尝试在数据库中更新并且无法保存 JobConnection 的任何引用时,它会产生干扰。即使在离开其声明和初始化的范围之后,上下文也会以某种方式存储对插入对象的引用。

解决方案:

可以有多种方法来解决这个问题。其中一种方法是将实例与上下文分离,以避免出现类似的孤立重复实例,从而导致我们的案例出现问题。这是我如何在代码中修复的示例:

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

代码中的另一个示例也有类似的问题,这里是解决方案。

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