简体   繁体   中英

The instance of entity type cannot be tracked

hello community I have a problem when I try to edit a model it tells me that I am trying to duplicate the primary key and I don't know why this happens.

Error System.InvalidOperationException: The instance of entity type 'Cotizacion' cannot be tracked because another instance with the same key value for {'CotizacionId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.

this is my controller code:

   [HttpPut]
        public async Task<ActionResult> Put(Cotizacion cotizacion)
        {           
            var cotizacionoriginal = context.Cotizaciones.Where(x => x.CotizacionId == cotizacion.CotizacionId).FirstOrDefault();                 
            cotizacionoriginal = cotizacion;
            context.Update(cotizacion);
            context.SaveChanges();
            return NoContent();
        }

this is my model cotizacion:

 public class Cotizacion
    {
        [Key]
        public Guid CotizacionId { get; set; }
        public Guid InquilinoId { get; set; }
        public int Folio { get; set; }
        public DateTime? FechaCotizacion { get; set; }
        public DateTime? FechaVencimiento { get; set; }
        public DateTime? FechaCreacion { get; set; }
        public DateTime? FechaModificacion { get; set; }
        public bool EsBorrador { get; set; }
        public double Total { get; set; }
        public string Comentario { get; set; }
        public bool Aceptada { get; set; }

       
        public Guid CarritoId { get; set; }
        public Guid ClienteId { get; set; }
        public Guid? DireccionId { get; set; }
        public Guid? ContactoId { get; set; }

         
        public virtual Carrito Carrito { get; set; }
        public virtual Cliente Cliente { get; set; }
        public virtual Direccion Direccion { get; set; }
        public virtual Contacto Contacto { get; set; }
    }

this is my model cliente:

public class Cliente
    {
        public Guid ClienteId { get; set; }
        public Guid InquilinoId { get; set; }

        [Required(ErrorMessage = "El campo {0} es requerido")]
        public string Nombre { get; set; }

        [Required(ErrorMessage = "El campo Razón Social es requerido")]
        public string Razon_social { get; set; }

        [Required(ErrorMessage = "El campo {0} es requerido")]
        public string Rfc { get; set; }

        [Required(ErrorMessage = "El campo {0} es requerido")]
        public string Email { get; set; }
        public int Telefono { get; set; }
        public int Celular { get; set; }
        public bool Es_Cliente { get; set; }
        public bool Es_Proveedor { get; set; }
    
        public virtual List<Contacto> Contacto { get; set; } = new List<Contacto>();      
        public virtual List<Direccion> Direccion { get; set; } = new List<Direccion>();
        public virtual List<ClienteTipodeConcepto> ClienteTipodeConcepto { get; set; } = new List<ClienteTipodeConcepto>();
        public virtual List<ClienteConcepto> ClienteConcepto { get; set; } = new List<ClienteConcepto>();
        public virtual Cliente Empresa { get; set; }         
    }

this is my model carrito:

public class ArticuloCarrito
    {
        
        [Key]      
        public Guid ArticuloCarritoId { get; set; }
        public Guid ProductoId { get; set; }
        public int Cantidad { get; set; }
       
        public decimal PrecioPublico { get; set; }
        public decimal Total// { get; set; }
        {
            get
            {
                return PrecioPublico * Cantidad;
            }
        }      
        public virtual Carrito Carrito { get; set; }
        public virtual Producto Producto { get; set; }     
    }

    public class Carrito
    {
        [Key]     
        public Guid CarritoId { get; set; }

      
        public virtual ICollection<ArticuloCarrito> Articulos { get; set; }     
        public decimal Subtotal
        {
            get
            {
                decimal total = 0;
                if (Articulos is null)
                {
                    total = 0;
                }
                else
                {
                    foreach (var item in Articulos)
                    {
                        total += item.Total;
                    }
                }

                return total;
            }
        }   
        public decimal IVA
        {
            get
            {
                double sub = Convert.ToDouble(Subtotal);

                return (Convert.ToDecimal(sub * .16));
            }
        }       
        public decimal Total
        {
            get
            {
                double sub = Convert.ToDouble(Subtotal);

                return (Convert.ToDecimal(sub * 1.16));
            }
        }
        public DateTime UltimoAcceso { get; set; }
        public int TiempoDeVidaEnSegundos { get; set; } = 1800;       
    }

also try an endpoint like this:

 [HttpPut]
        public async Task<ActionResult> Put(Cotizacion cotizacion)
        {
            var cotizacionDB = await context.Cotizaciones.FirstOrDefaultAsync(x => x.CotizacionId == cotizacion.CotizacionId);
            if (cotizacionDB == null) { return NotFound(); }

            cotizacionDB = mapper.Map(cotizacion, cotizacionDB);

            await context.Database.ExecuteSqlInterpolatedAsync($"delete from Cotizaciones WHERE CotizacionId = {cotizacion.CotizacionId};");

            cotizacionDB.Cliente = cotizacion.Cliente;
            cotizacionDB.Carrito = cotizacion.Carrito;

            await context.SaveChangesAsync();
            return NoContent();
        }

but it didn't work

my new try:

 [HttpPut]
        public async Task<ActionResult> Put(Cotizacion cotizacion)
        {
            var cotizacionoriginal = context.Cotizaciones.Where(x => x.CotizacionId == cotizacion.CotizacionId).FirstOrDefault();
            cotizacionoriginal.Carrito= cotizacion.Carrito;
            if (cotizacionoriginal != null)
            {
                
                context.Entry(cotizacionoriginal).State = EntityState.Detached;
            }

            context.Entry(cotizacion).State = EntityState.Modified;
         
           await context.SaveChangesAsync();
           return NoContent();
        }

The reason that you are running into this issue is due to the code in your controller. On this line you are tracking a Cotizacion entity

var cotizacionoriginal = context.Cotizaciones.Where(x => x.CotizacionId == cotizacion.CotizacionId).FirstOrDefault();   

And on this line you are attempting to track another Cotizacion entity with the same key value.

context.Update(cotizacion);

Essentially you have three ways that you can handle this.

Option #1 Detach local entry and attach updated entry:

var cotizacionoriginal = context.Cotizaciones.Where(x => x.CotizacionId == cotizacion.CotizacionId).FirstOrDefault();  

// check if local is not null 
if (cotizacionoriginal != null)
{
    // detach
    _context.Entry(cotizacionoriginal).State = EntityState.Detached;
}
// set Modified flag in your entry
_context.Entry(cotizacion).State = EntityState.Modified;

// save 
_context.SaveChanges();

Option #2 Update the individual properties you want to change

   [HttpPut]
        public async Task<ActionResult> Put(Cotizacion cotizacion)
        {           
            var cotizacionoriginal = context.Cotizaciones.Where(x => x.CotizacionId == cotizacion.CotizacionId).FirstOrDefault();                 
            cotizacionoriginal.Folio = cotizacion.Folio;
            cotizacionoriginal.Total = cotizacion.Total; //Continue as required
            context.Update(cotizacionoriginal );
            context.SaveChanges();
            return NoContent();
        }

Option #3 Simply update that value if it's guaranteed that it will always exist and will never cause any issues (not recommended)

   [HttpPut]
        public async Task<ActionResult> Put(Cotizacion cotizacion)
        {           
            context.Update(cotizacion);
            context.SaveChanges();
            return NoContent();
        }

If you are attempt to update items within the Cotizacion type as well (for example Nombre inside the Cliente) then this won't work. You can update the reference to the Cliente inside the Cotizacion, but in order to update the subitems you will need to perform those separately.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM