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

时间:2020-06-08 01:50:32

标签: c# entity-framework entity-framework-core .net-core-3.1

我从实体基类中得到了相同的键值运行时异常。我尝试了很少的在线解决方案。谁能帮我解决此问题?当我尝试更新时,以下代码行抛出异常:

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

框架:.netcore 3.1

错误:

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

这里是电话:

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();
        }
    }
}

这是整个存储库类:

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; }
    }

JobConnection模型-

 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");
        });

上下文-

SHOW INDEXES
FROM job_connection

job_connection  0   PRIMARY 1   jobconnectionid A   63              BTREE       

表格-

package com.example.test;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class bilgiCek extends AppCompatActivity {
    public static void telefonBilgi(){
        TelephonyManager bilgiler = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); // Error is here.

        String simUlke = bilgiler.getSimCountryIso();
        String netUlke = bilgiler.getNetworkCountryIso();
        String imei = bilgiler.getImei();
        String simNo = bilgiler.getSimSerialNumber();
        String sesMail = bilgiler.getVoiceMailNumber();
        System.out.println("İmei Numarası" + imei);
    }

}

2 个答案:

答案 0 :(得分:0)

似乎您没有使用类似entity.HasKey(a => a.Id);之类的东西来表示主键。因此,数据库行ID与您要更新的内存中的对象冲突。

在调用this.RepositoryContext.SaveChanges();之前,应该调试并检查要更新的对象的ID。

答案 1 :(得分:0)

最后,我通过分离EntityState解决了此问题。我非常感谢您分享您的想法-这有助于您认真思考。请在下面找到问题和正确的解决方案。

问题:

至少有一个孤立的跟踪实例无法与我要在数据库中更新的正确实例一起使用-基本上,这是一个重复实例,当上下文尝试在数据库中进行更新时,该实例受到干扰,并且无法保存任何实例JobConnection的参考。即使离开声明和初始化的范围,上下文仍然以某种方式将引用存储在插入的对象上。

解决方案:

可能有多种方法可以解决此问题。一种方法是将实例与上下文分离,以避免出现类似的孤立重复实例,这会导致我们的案例出现问题。这是我如何固定代码的示例:

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

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

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