我正在使用Angular和.Net Core开发Web API。当我尝试在此端点进行更新时,出现以下错误:
执行请求时发生未处理的异常。
System.InvalidOperationException
:无法跟踪实体类型'Etapa'的实例,因为已经跟踪了具有相同的{'IdEtapa'}键值的另一个实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.ThrowIdentityConflict(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKey key, InternalEntityEntry entry, Boolean updateDuplicate)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges, Nullable`1 forceStateWhenUnknownKey)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode node, Boolean
force)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode node, TState state, Func`3 handleNode)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode node, TState state, Func`3 handleNode)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode node, TState state, Func`3 handleNode)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.AttachGraph(InternalEntityEntry rootEntry, EntityState entityState, Boolean forceStateWhenUnknownKey)
at Microsoft.EntityFrameworkCore.DbContext.SetEntityState(InternalEntityEntry entry, EntityState entityState)
at Microsoft.EntityFrameworkCore.DbContext.SetEntityState[TEntity](TEntity entity, EntityState entityState)
at Microsoft.EntityFrameworkCore.DbContext.Update[TEntity](TEntity entity)
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.Update(TEntity entity)
at Foha.Repositories.DataRepository`1.Update(T entity) in C:\Users\Federico\Desktop\Foha\Repositories\DataRepository.cs:line 22
at Foha.Controllers.EtapaController.PutEtapa(Int32 id, EditEtapaDto editEtapaDto) in C:\Users\Federico\Desktop\Foha\Controllers\EtapaController.cs:line 208 "
这是控制器:
namespace Foha.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class EtapaController : ControllerBase
{
private readonly fohaContext _context;
private readonly IMapper _mapper;
private readonly IDataRepository<Etapa> _repo;
private readonly IDataRepository<EtapaEmpleado> _repo2;
public EtapaController(fohaContext context, IMapper mapper,
IDataRepository<Etapa> repo,IDataRepository<EtapaEmpleado> repo2)
{
_context = context;
_mapper = mapper;
_repo = repo;
_repo2 = repo2;
}
[HttpPut("{id}")]
public async Task<IActionResult> PutEtapa([FromRoute] int id, [FromBody]
EditEtapaDto editEtapaDto)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != editEtapaDto.IdEtapa)
{
return BadRequest();
}
// _context.Entry(editEtapaDto).State = EntityState.Detached;
var preEtapa = _mapper.Map<Etapa>(editEtapaDto);
//Prueba
foreach(var a in preEtapa.EtapaEmpleado)
{
var preEtapaEmpleado=_mapper.Map<EtapaEmpleado>(a);
if(_context.EtapaEmpleado.Where(z=>z.IdEmpleado==preEtapaEmpleado.IdEmpleado).Count()>0 && _context.EtapaEmpleado.Where(x=>x.IdEtapa==preEtapaEmpleado.IdEtapa).Count()>0)
{
var tiempoAntes=_context.EtapaEmpleado.AsNoTracking().FirstOrDefault(z=>z.IdEmpleado==preEtapaEmpleado.IdEmpleado && z.IdEtapa==preEtapaEmpleado.IdEtapa);
var condicion=String.IsNullOrEmpty(tiempoAntes.TiempoParc);
//SI ESTA PAUSADO O FINALIZADO
if(condicion==false)
{
string[] arrTAntesStr=tiempoAntes.TiempoParc.Split(':');
string[] arrTDespuesStr=preEtapaEmpleado.TiempoParc.Split(':');
int[] tiempoAntesArrInt= Array.ConvertAll(arrTAntesStr,Int32.Parse);
int[] tiempoDespuesArrInt=Array.ConvertAll(arrTDespuesStr,Int32.Parse);
int[] tiempoIntFinal={0,0,0,0};
int meLlevoUno=0;
string tiempoStringFinal=null;
for(int i=3;i>-1;i--)
{
switch(i){
default:
tiempoIntFinal[i]=tiempoAntesArrInt[i]+tiempoDespuesArrInt[i]+meLlevoUno;
meLlevoUno=tiempoIntFinal[i]/60;
tiempoIntFinal[i]=tiempoIntFinal[i]%60;
break;
case 0:
tiempoIntFinal[i]=tiempoAntesArrInt[i]+tiempoDespuesArrInt[i]+meLlevoUno;
break;
case 1:
tiempoIntFinal[i]=tiempoAntesArrInt[i]+tiempoDespuesArrInt[i]+meLlevoUno;
meLlevoUno=tiempoIntFinal[i]/24;
tiempoIntFinal[i]=tiempoIntFinal[i]%24;
break;
}
}
var builder = new StringBuilder();
for(int j=0;j<tiempoIntFinal.Length;j++)
{
if(tiempoIntFinal[j]<10)
{
builder.Append("0");
}
builder.Append(tiempoIntFinal[j]);
if(j!=3)
{
builder.Append(":");
}
tiempoStringFinal=builder.ToString();
}
preEtapaEmpleado.TiempoParc=tiempoStringFinal;
}
try{
_repo2.Update(preEtapaEmpleado);
}
catch(DbUpdateConcurrencyException){
throw;
}
}
else{
try{
_repo2.Add(preEtapaEmpleado);
}
catch(DbUpdateConcurrencyException)
{
throw;
}
}
await _repo2.SaveAsync(preEtapaEmpleado);
}
//IN THE NEXT LINE IS THE PROBLEM
_repo.Update(preEtapa);
await _repo.SaveAsync(preEtapa);
return StatusCode(201,preEtapa);
}
这是我的IDataRepository
:
namespace Foha.Repositories
{
public interface IDataRepository<T> where T : class
{
void Add(T entity);
void Update(T entity);
void Delete(T entity);
Task<T> SaveAsync(T entity);
}
}
DataRepository:
using System.Threading.Tasks;
using Foha.Models;
namespace Foha.Repositories
{
public class DataRepository<T> : IDataRepository<T> where T : class
{
private readonly fohaContext _context;
public DataRepository(fohaContext context)
{
_context = context;
}
public void Add(T entity)
{
_context.Set<T>().Add(entity);
}
public void Update(T entity)
{
_context.Set<T>().Update(entity);
}
public void Delete(T entity)
{
_context.Set<T>().Remove(entity);
}
public async Task<T> SaveAsync(T entity)
{
await _context.SaveChangesAsync();
return entity;
}
}
}
型号:
using System;
using System.Collections.Generic;
namespace Foha.Models
{
public partial class Etapa
{
public int IdEtapa { get; set; }
public int? IdTipoEtapa { get; set; }
public DateTime? DateIni { get; set; }
public DateTime? DateFin { get; set; }
public bool? IsEnded { get; set; }
public string TiempoParc { get; set; }
public string TiempoFin { get; set; }
public int? IdTransfo { get; set; }
public int? IdEmpleado { get; set; }
public string Hora { get; set; }
public DateTime? InicioProceso { get; set; }
public int? IdColor { get; set; }
public int? NumEtapa{get;set;}
public Colores IdColorNavigation { get; set; }
public TipoEtapa IdTipoEtapaNavigation { get; set; }
public Transformadores IdTransfoNavigation { get; set; }
public ICollection<EtapaEmpleado> EtapaEmpleado {get;set;}
}
}
DTO:
namespace Foha.Dtos
{
public class EditEtapaDto
{
public int IdEtapa { get; set; }
public int? IdTipoEtapa { get; set; }
public DateTime? DateIni { get; set; }
public DateTime? DateFin { get; set; }
public bool? IsEnded { get; set; }
public string TiempoParc { get; set; }
public string TiempoFin { get; set; }
public int? IdTransfo { get; set; }
public int? IdEmpleado { get; set; }
public string Hora { get; set; }
public DateTime? InicioProceso { get; set; }
public int? IdColor { get; set; }
public int? NumEtapa{get;set;}
public Colores IdColorNavigation { get; set; }
public TipoEtapa IdTipoEtapaNavigation { get; set; }
public Transformadores IdTransfoNavigation { get; set; }
public ICollection<EtapaEmpleado> EtapaEmpleado {get;set;}
}
}
我试图在其他帖子中找到答案,但我不知道出了什么问题。