如何通过 PUT 方法更新 ICollection 的 属性?
How to update a property of an ICollection through PUT method?
我有两个 classes,Ignicoes 和 Ocorrencias:
伊格尼科斯 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; }
}
奥科伦西亚斯 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; }
}
如您所见,每个 Ignicao 都有一个 Ocorrencias 列表。
我通过调用 PUT 方法的 ajax 请求更新了 Ignicao 的 属性“Estado”
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)
}
});
}
这是我的 PUT 方法:
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();
}
我在 PUT 方法中尝试做的是,每当 Ignicao 的 属性“Estado”发生变化时,同时 属性 每个 Ocorrencia 的 Estado 28=] ListaOcorrencias 也发生了变化。
现在我在 PUT 方法中显示的代码。它没有给我一个错误,但是当我尝试调试时,它会跳过它在循环中的代码。
为什么会这样?
根据上面的评论,ig.ListaOcorrencias
集合未从数据库中提取。需要启用延迟加载才能使上述代码正常工作。您也可以像这样使用 Include 加载相关集合:_context.Ignicoes.Include(i => i.ListaOccurrencias).FirstOrDefault(ignicaoId => ignicaoId.Id.Equals(id));
,这是一个很好的解决方案,因为您总是想加载相关集合。
进一步阅读:
https://docs.microsoft.com/en-us/ef/core/querying/related-data
我有两个 classes,Ignicoes 和 Ocorrencias: 伊格尼科斯 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; }
}
奥科伦西亚斯 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; }
}
如您所见,每个 Ignicao 都有一个 Ocorrencias 列表。 我通过调用 PUT 方法的 ajax 请求更新了 Ignicao 的 属性“Estado”
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)
}
});
}
这是我的 PUT 方法:
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();
}
我在 PUT 方法中尝试做的是,每当 Ignicao 的 属性“Estado”发生变化时,同时 属性 每个 Ocorrencia 的 Estado 28=] ListaOcorrencias 也发生了变化。 现在我在 PUT 方法中显示的代码。它没有给我一个错误,但是当我尝试调试时,它会跳过它在循环中的代码。 为什么会这样?
根据上面的评论,ig.ListaOcorrencias
集合未从数据库中提取。需要启用延迟加载才能使上述代码正常工作。您也可以像这样使用 Include 加载相关集合:_context.Ignicoes.Include(i => i.ListaOccurrencias).FirstOrDefault(ignicaoId => ignicaoId.Id.Equals(id));
,这是一个很好的解决方案,因为您总是想加载相关集合。
进一步阅读:
https://docs.microsoft.com/en-us/ef/core/querying/related-data