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

Problema com Context.Save

Caros, estou com dúvida nos Exercícios 4 e 5 da aula 7.

No momento da salvar a venda no banco o EF libera um erro dizendo que "Um objeto de entidade não pode ser referenciado por várias instâncias de IEntityChangeTracker" Link da Exception:

http://imageshack.com/a/img540/5877/TzgwF1.jpg

Segue o código da vendaDAO:

 public void Adiciona(Venda venda)
        {

            foreach (Produto produto in venda.Produtos)
            {
                contexto.Produtos.Attach(produto);
            }

            contexto.Vendas.Add(venda);
            contexto.SaveChanges();


        }

Segue código controller:

public ActionResult CompletaPedido(int usuarioId)
        {
            // use o usuariosDAO para buscar o usuario de id usuarioId
            UsuariosDAO udao = new UsuariosDAO();
            Usuario usuario = udao.BuscaPorId(usuarioId);
            Venda venda = this.Carrinho.CriaVenda(usuario);
            // utilize o dao para gravar a venda no banco de dados
            VendasDAO vdao = new VendasDAO();
            vdao.Adiciona(venda);
            this.Carrinho = new Carrinho();
            return RedirectToAction("Index");
        }
4 respostas

Oi Leonardo

O problema do seu código é que no controller você está utilizando as classes UsuariosDAO (para buscar o usuário do banco de dados) e VendasDAO (para gravar a compra no banco).

Cada um desse DAOs está utilizando uma instância diferente do IDbContext para gravar as informações no banco de dados da aplicação e por isso, o EF está lançando a exceção. Para corrigir o problema, você precisa fazer com que os dois DAOs compartilhem a mesma instância do IDbContext.

Para fazer o compartilhamento do IDbContext, você pode utilizar a injeção de dependências que é explicada no exercício 12 do capítulo 2 do curso: http://www.alura.com.br/course/entity-framework/section/2/exercise/12

Perfeito Victor! Muito obrigado pela resposta. Quando se trata de projetos de aprendizado eu evito "condensar" código. Estava fazendo quase tudo sem ninject.

Há alguma forma de utilizar a mesma instância sem ser por injeção?

Muito obrigado pela resposta e ajuda. abs

solução!

Você pode adicionar um construtor nos DAOs para receber o contexto e depois no código do controller você pode passar a mesma instância para todos os DAOs:

public ActionResult CompletaPedido(int usuarioId)
{
  using(EntidadesContext context = new EntidadesContext())
  {
    // Instancia os dois DAOs passando o mesmo context:
    UsuariosDAO udao = new UsuariosDAO(context);
    VendasDAO vdao = new VendasDAO(context);

    // Usa os DAOs e devolve a resposta.
  }
}

Perfeito! Tinha feito isto e resolvido. Muito obrigado pelo apoio. Dúvida resolvida. abs