Conforme sugestão do professor, segue minhas classes e o objeto JSON antigo e atual para melhor exemplificar o relacionamento. No objeto JSON abaixo o pacote possui id: 6 e possui dois serviços, um com id:12 e outro com id:15, esse pacote é enviado para o cliente, que altera os serviços que contém neste pacote. Passando este pacote a possuir dois serviços, um serviço com id:12 e outro com id:20 . Ou seja, o serviço id:12 continuou no pacote, o serviço id:15 foi removido e o serviço id:20 foi adicionado. Problema: Tenho que fazer todo o trabalho manualmente, verificando qual pacote foi adicionado, removido, mantido. Existe alguma forma de fazer para não ter que analisar item a item(foreach consultando o banco) ou excluindo tudo e adicionando tudo novamente?(Como fiz esta no fim do código, exclui tudo e adicionei novamente. Não acho legal isso mas foi a única maneira que encontrei) Se possível gostaria que alguém escreve o método update dentro desse contexto. Percebi que na versão core não existe o método AddOrUpdate ou a biblioteca graphdiff. Estou correto?
public class Pacote
{
public int Id { get; set; }
public string Descricao { get; set; }
public float Valor { get; set; }
public virtual IList<PacoteServico> ServicosLink { get; set; }
}
public class Servico
{
public int Id { get; set; }
public string Descricao { get; set; }
public float Valor { get; set; }
public virtual IList<PacoteServico> PacotesLink { get; set; }
}
public class PacoteServico
{
public virtual Servico Servico { get; set; }
public int ServicoId { get; set; }
public virtual Pacote Pacote { get; set; }
public int PacoteId { get; set; }
}
Meu método Rest
public IActionResult Update(long id, [FromBody] Pacote pacote)
{
//Não inseri meu código para não criar mais dúvida.
//Como deve ser o código nesse campo para atualizar o relacionamento do pacote com meu serviço? Comparar objetos antigo com o novo objeto (abaixo esta o objeto JSON)
}
Meu objeto Json Antigo retornado para o cliente através do GET
{
"id": 6,
"descricao": "Meu pacote 1",
"valor": 22,
"servicosLink": [
{
"servico": {
"id": 12,
"descricao": "Meu servico A",
"valor": 60,
"pacotesLink": []
},
"servicoId": 12,
"pacoteId": 6,
"quantServicos": 5
},
{
"servico": {
"id": 15,
"descricao": "Meu servico B",
"valor": 1,
"pacotesLink": []
},
"servicoId": 15,
"pacoteId": 6,
"quantServicos": 5
}
]
}
Meu Novo objeto atualizado pelo cliente
{
"id": 6,
"descricao": "Meu pacote 1",
"valor": 25,
"servicosLink": [
{
"servico": {
"id": 12,
"descricao": "Meu servico A",
"valor": 60,
"pacotesLink": []
},
"servicoId": 12,
"pacoteId": 6,
"quantServicos": 5
},
{
"servico": {
"id": 20,
"descricao": "Meu servico C",
"valor": 1,
"pacotesLink": []
},
"servicoId": 20,
"pacoteId": 6,
"quantServicos": 3
}
]
}
Esta é a forma que fiz meu update, deixei só o essencial Notem que fiz uma transaction, pois removo os relacionamentos e depois adiciono. Este é um tipo de operação que não pode funcionar somente o remove ou add, caso contrario comprometeria os meus dados se houvesse um erro em um dos métodos.
[HttpPut("{id}")]
public IActionResult Update(long id, [FromBody] Pacote newPacote)
{
Pacote oldPacote;
oldPacote = context.Pacotes
.Include(p => p.ServicosLink)
.ThenInclude(ps => ps.Servico)
.Single(p => p.Id == newPacote.Id);
using (var dbContextTransaction = context.Database.BeginTransaction())
{
try
{
foreach (PacoteServico ps in oldPacote.ServicosLink)
{
context.Set<PacoteServico>().Remove(ps);
}
Util.ExibeChangeTracks(context.ChangeTracker.Entries());
context.SaveChanges();
foreach (PacoteServico ps in newPacote.ServicosLink)
{
oldPacote.ServicosLink.Add(new PacoteServico()
{
Pacote = oldPacote,
Servico = context.Servicos.Single(s => s.Id == ps.Servico.Id),
QuantServicos = ps.QuantServicos,
});
}
Util.ExibeChangeTracks(context.ChangeTracker.Entries());
context.SaveChanges();
dbContextTransaction.Commit();
return new NoContentResult();
}
catch (Exception e)
{
dbContextTransaction.Rollback();
return BadRequest(e.Message);
}
}
}