简体   繁体   中英

How to update a property of an ICollection through PUT method?

I have two classes, Ignicoes and Ocorrencias: Ignicoes class:

 public class Ignicoes
{
    public enum EstadoIgnicao
    {
        aceite,
        emAvaliacao,
        concluido,
        recusado
    }

    public Ignicoes()
    {
        ListaOcorrencias = new HashSet<Ocorrencias>();

    }

    
    [Key]
    [Required]
    public int Id { get; set; }

    [Required]
    public string Latitude { get; set; }

    [Required]
    public string Longitude { get; set; }

    //estado(recusada, aceite, em avaliacao, concluido)
  
    [Required]
    public EstadoIgnicao Estado { get; set; }

  
    public DateTime DataInicioPropostaIgnicao { get; set; }
    public DateTime DataDecisaoIgnicao { get; set; }


    //lista de ocorrencias 
    public virtual ICollection<Ocorrencias> ListaOcorrencias { get; set; }

}

Ocorrencias class:

      public class Ocorrencias
{

    public enum EstadoOcorrencia
    {
        aceite,
        emAvaliacao,
        recusado
    }

    [Key]
    public int Id { get; set; }

    /// <summary>
    /// código que identifica de forma única o aparelho que comunica a ocorrência
    /// </summary>
    [Required]
    public string Dispositivo { get; set; }


    /// <summary>
    /// data da ocorrencia
    /// </summary>
    [Required]
    public DateTime DataOcorrencia { get; set; }

    /// <summary>
    /// coordenadas GPS - Latitude
    /// </summary>
    [Required]
    public string Latitude { get; set; }

    /// <summary>
    /// coordenadas GPS - Logitude
    /// </summary>
    [Required]
    public string Longitude { get; set; }

    /// <summary>
    /// Azimute do ?angulo formado entre o Polo Norte e o fogo
    /// </summary>
    [Required]
    public string Azimute { get; set; }


    /// <summary>
    /// Foto a provar a ocorrência
    /// </summary>
    [Required]
    public string Fotografia { get; set; }

    /// <summary>
    /// Nome a atribuir à fotografia guardada no disco rígido
    /// </summary>
    public string NomeFotografia { get; set; }

    /// <summary>
    /// estado da ocorrencia : aceite, em avaliação, recusado
    /// </summary>
    [Required]
    public EstadoOcorrencia Estado { get; set; }

    [ForeignKey("Ignicao")]
    [Display(Name = "Ignicao")]
    public int? IgnicaoFK { get; set; }
    public virtual Ignicoes Ignicao { get; set; }



}

As you can see every Ignicao has a list of Ocorrencias. I update the property "Estado" of the Ignicao through an ajax request that calls the PUT method

function atualizaBD(idmarcador, novoEstado, latitude, longitude) {
    $.ajax
        ({
            url: `/api/IgnicoesAPI/${idmarcador}`,
            type: 'PUT',
            contentType: "application/json; charset=utf-8",
            dataType: 'json',
            data: JSON.stringify({
                Id: idmarcador,
                Estado: novoEstado,
                Latitude: latitude,
                Longitude: longitude
            }),
            async: true,
            processData: false,
            cache: false,
            success: function (result) {
                 connection.invoke("PostMarker").catch(function (err) {
                              return console.error(err.toString());
                 });
            },
            error: function () {
                alert(novoEstado)
            }
        });
}

Here is my PUT method:

   public async Task<IActionResult> PutIgnicoes([FromRoute] int id, [FromBody] Ignicoes ignicao)
    {

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }


        if (id != ignicao.Id)
        {
            return BadRequest();
        }

        else
        {
            var dataDecisao = DateTime.Now;
            var ig = _context.Ignicoes.FirstOrDefault(ignicaoId => ignicaoId.Id.Equals(id));
            if (ig != null)
            {



                ig.Estado = ignicao.Estado;

                //é necessário mudar o estado das ocorrencias que fazem parte da lista de ocorrencias desta ignição
                var listaOocrrencias = ig.ListaOcorrencias.ToList();
                for(int i=0; i < listaOocrrencias.Count;i++)
                {
                    if (ignicao.Estado == Ignicoes.EstadoIgnicao.aceite)
                    {
                        ig.ListaOcorrencias.ElementAt(i).Estado = Ocorrencias.EstadoOcorrencia.aceite;
                    }
                    else
                    {
                        if (ignicao.Estado == Ignicoes.EstadoIgnicao.recusado)
                        {
                            ig.ListaOcorrencias.ElementAt(i).Estado = Ocorrencias.EstadoOcorrencia.recusado;
                        }

                    }

                }
    
                    ig.Latitude = ignicao.Latitude;
                    ig.Longitude = ignicao.Longitude;
                    ig.DataDecisaoIgnicao = dataDecisao;



            }
            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!IgnicoesExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }
        }

        return NoContent();
    }

What I'm trying to do in the PUT method, is whenever the property "Estado" of an Ignicao is changed, simultaneously, the property Estado of every Ocorrencia in the property ListaOcorrencias is also changed. Right now the code that I show in the PUT method. It doesn't give me an error but when I tried to debbug it skips the code that it's inside the loop for. Why is this happening?

From the comment above, the ig.ListaOcorrencias collection was not hydrated from the database. Lazy loading would need to be enabled for the above code to work. You could also eager load the related collection using Include like this: _context.Ignicoes.Include(i => i.ListaOccurrencias).FirstOrDefault(ignicaoId => ignicaoId.Id.Equals(id)); , which is a good solution here since you always want to load the related collection.

Further reading:

https://docs.microsoft.com/en-us/ef/core/querying/related-data

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