Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Somar campos entre duas views diferentes

Bom, eu estou criando um controle de estoque e estou fazendo a tela de entrada de produtos, e quero que a pessoa primeiro cadastre uma nova entrada de um produto, após isso eu listo os produtos cadastrados e então na própria lista terá um botão para cada novo produto onde a pessoa irá clicar e ele ira somar com a quantidade da outra tabela de produto

basicamente eu tenho uma tabela produto que tem o campo int qtdEstoque e outra tabala movEntrada que tem um campo int Quantidade.... A pessoa clica em Criar Novo Registro e ela preenche os campos da Entrada e depois salva, após salvar ela é redirecionada para uma lista com os produtos salvados, nessa lista cada produto tem um botão onde vai ser feito a operação de soma.

Para a operação eu criei uma Action no Controller de Entrada

public async Task<IActionResult> Entrada(int idProduto, int idEntrada)
        {
            var entrada = await _context.movEntradas
                .SingleOrDefaultAsync(m => m.movEntradaID == idEntrada);
            var produto = await _context.Produtos
                .SingleOrDefaultAsync(m => m.ProdutoID == idProduto);

                produto.QtdEstoque = produto.QtdEstoque + entrada.Quantidade;
                _context.SaveChanges();
                return RedirectToAction(nameof(Index));
        }

Porém ao clicar no botão aparece esse erro: An unhandled exception occurred while processing the request. NullReferenceException: Object reference not set to an instance of an object.

Fiz uns testes usando produto.QtdEstoque++ e entrada.Quantidade++ e ambos funcionaram, agora por que não consigo somar esses dois campos?

5 respostas

Olá, Gabriel. Tudo bom?

Quando a exceção NullReferenceException ocorre, o Visual Studio aponta para qual variável?

E esse é o erro que me é retornado: An unhandled exception occurred while processing the request. NullReferenceException: Object reference not set to an instance of an object. MercadoSaoBento.Controllers.movEntradasController+d__5.MoveNext() in movEntradasController.cs + produto.QtdEstoque += movEntrada.Quantidade;

Desculpa , esse erro que eu mandei agora é de um outro modo que eu estou fazendo, vou explicar mais ou menos

Eu fiz um crud pra tabela de entrada de produtos, no create a pessoa cadastra os dados e a quantidade e eu quero que quando a pessoa clique em gravar, a quantidade que ela colocou no campo seja somado com a quantidade do estoque da outra tabela de produto Meu create do controller esta assim:

public async Task<IActionResult> Create([Bind("movEntradaID,nmrDocumento,dataEntrada,Quantidade,obs,ProdutoID")] movEntrada movEntrada, int id)
{
    if (ModelState.IsValid)
    {
        context.Add(movEntrada);
        await context.SaveChangesAsync();

        var produto = await context.Produtos.SingleOrDefaultAsync(m => m.ProdutoID == id);
        produto.QtdEstoque += movEntrada.Quantidade;
        await context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    ViewData["ProdutoID"] = new SelectList(_context.Produtos, "ProdutoID", "Nome", movEntrada.ProdutoID);
    return View(movEntrada);
}
solução!

Gabriel, suspeito que o método context.Produtos.SingleOrDefaultAsync esteja retornando nulo!

Você poderia verificar se o argumento id está sendo preenchido corretamente?

No mais, o método SingleOrDefaultAsync devolve nulo quando o predicado passado por argumento não é satisfeito por nenhum item de uma coleção. Se o produto é obrigatório para o funcionamento do seu código, é melhor usar o método SingleAsync - este último lança uma exceção quando o item não é encontrado e previne você de exceções de referência nula.

Desculpa a demora para responder, acabei esquecendo, mas eu consegui resolver o problema!

O problema era que eu estava passando uma assinatura a mais no método create sem necessidade

O int id que eu passava como assinatura estava me retornando falso, por que realmente não estava recebendo nada.

Eu havia me esquecido que na classe desse método eu já tinha uma chave estrangeira que denotava o ID do Produto.

Então o que eu fiz foi basicamente:

public async Task<IActionResult> Create([Bind("movEntradaID,nmrDocumento,dataEntrada,Quantidade,obs,ProdutoID")] movEntrada movEntrada)
        {

            if (ModelState.IsValid)
            {
                _context.Add(movEntrada);
                var produto = await _context.Produtos
                .FirstAsync(m => m.ProdutoID == movEntrada.ProdutoID);
                produto.QtdEstoque += movEntrada.Quantidade;
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            ViewData["ProdutoID"] = new SelectList(_context.Produtos, "ProdutoID", "Nome", movEntrada.ProdutoID);
            return View(movEntrada);
        }

Então eu criei uma variável e puxei a tabela Produtos através do contexto, então falei que a chave primária da minha classe Produto é a mesma da chave estrangeira (ProdutoID)

Então eu consegui buscar os valores da tabela Produto e somei a Quantidade que o usuário colocou com o estoque do Produto!

Obrigado pela ajuda, ela me deu um norte para entender essa parte!

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software