none
Problema após manipular BD com ado.net entity framework RRS feed

  • Pergunta

  • Olá pessoal, estou com um grande problema.

    Tenho uma página que usa Jquery Mobile e o que acontece é o seguinte:

    Estou fazendo um site na qual o objetivo é criar ambientes onde você pode cadastrar portas em cada ambiente. Por exemplo:

    Ambiente 1 é composto pelas portas 1, 2 e 3.

    Ambiente 2 é composto pelas portas 4 e 5. Etc...

    No meu banco de dados criei uma tabela tb_ambientes onde cadastro os ambientes (id, nome, descrição) e uma tb_portas onde tenho (id, porta, descrição, id_ambiente) e o id_ambiente desta segunta tabela informa a qual ambiente a porta pertence.

    No meu projeto em asp.net MVC com C# tenho a seguinte situação:

    Na página index eu listo todos os ambientes cadastrados na tb_ambientes. Quando clico em algum ambiente sou levado a uma pagina de edição para o cara poder editar aquele ambiente (adicionar ou remover porta, mudar nome ou descrição).

    Quando eu clico em um ambiente e edito ele (adiciono uma porta por exemplo) ele edita normalmente e após clicar no botão salvar sou levado a página index novamente. Neste momento, se eu clicar naquele mesmo ambiente a qual eu editei, quando eu acesso não aparece as alterações feitas. Apenas se eu dou F5 (atualizo a pagina) é que as alterações são mostradas.

    Alguem já passou por isso?

    OBS.: isto acontece quando deleto um ambiente ou crio um novo. Ele não lista na index. Só lista se eu atualizar a página com F5.


    • Editado Rnl Rula quinta-feira, 21 de fevereiro de 2013 20:52
    quinta-feira, 21 de fevereiro de 2013 20:51

Todas as Respostas

  • Vc ja debugou para ver se ele esta passando pela função de index no controller? Nesta função vc tem a consulta no banco?

    Paulo Marcelo Dalbosco

    quinta-feira, 21 de fevereiro de 2013 21:04
  • Bom dia Paulo.

    Coloquei um breakpoint na Action do Index e verifiquei que ele só é chamado quando atualizo a tela com F5. Se eu entrar na tela pelos botões da minha interface ele não é chamado.

    Obs.: Os botões chamam "/Ambientes/Index" onde "Ambiente" é o controller e "Index" a action onde coloquei o breakpoint.

    Agradeço desde já.

    sexta-feira, 22 de fevereiro de 2013 11:18
  • As suas views vc criou por scaffloud?

    Microsoft Communit Contributor
    Twitter: @MayogaX
    Blog: Dev Blog

    sexta-feira, 22 de fevereiro de 2013 11:56
  • Não. Criei na mão mesmo.

    Obs.: Estou usando ADO.NET Entity Framework para me relacionar com o BD.

    sexta-feira, 22 de fevereiro de 2013 12:43
  • Faz o seguinte, faz uma cópia da sua view "Index", depois vai no Controller e clica com o botão direito em cima do nome da função "Index", quando abrir o menu clica em "Add View", coloque como esta na imagem. Ele vai criar uma nova View com o nome Index, ae vc soh copia os elementos da sua outra view para esta nova.



    Paulo Marcelo Dalbosco

    sexta-feira, 22 de fevereiro de 2013 13:06
  • Fiz desta forma, porém continua da mesma forma.

     

    Passo a passo como eu fiz:

    1 - Renomeei minha Index para IndexBkp.

    2 - Fui na Controller Ambiente, cliquei com o botão direito em cima da action Index e cliquei em Add View.

    3 - Configurei conforme a figura abaixo:

    4 - Peguei todo o meu conteúdo da página IndexBkp e mandei para a Index criada.

    Fiz o teste, porém não funcionou.

    Uma coisa que eu observei foi que: Quando eu entro na página Index e clico em Criar Ambiente, sou redirecionado para pagina onde crio um ambiente. Ai preencho o formulário e clico no botão Criar. Este botão cria meu novo ambiente no BD e no retorno eu do um":

    return RedirectToAction("Index");

    Ele me envia para a página Index novamente, porém o ambiente que eu acabei de criar não é listado e quando eu olho a URL está http://localhost:51274/Ambientes/Adicionar que é o caminho para criar o ambiente. Não deveria estar /Ambiente/Index?

    Grato.


    • Editado Rnl Rula sexta-feira, 22 de fevereiro de 2013 13:38
    sexta-feira, 22 de fevereiro de 2013 13:34
  • tente colocar assim:

    return RedirectToAction("Index", "Pata_Onde_Esta_View");
    No novo documento não copie tudo oq esta no antigo, apenas coloque os elementos do antigo.



    Paulo Marcelo Dalbosco


    sexta-feira, 22 de fevereiro de 2013 14:10
  • Tentei usar o:

    RedirectToAction("Index", "Pasta_Onde_Esta_View");

    mas não consegui. Teria algum exemplo de como ficaria a Pasta_Onde_Esta_View ?

    Grato.

    sexta-feira, 22 de fevereiro de 2013 15:01
  • Por exemplo, tenho uma view chamada Index na Pasta Chamado dentro da pasta Views. Chamado é minha entidade, a partir dela eu criei meu controller com o nome de ChamadoController, ele cria as Views tipadas.

    Return RedirectToAction("Index", "Chamado")
    coloque o código de sua view e da sua função controller aqui.

    Paulo Marcelo Dalbosco


    sexta-feira, 22 de fevereiro de 2013 16:38
  • Já tentei fazer desta forma, inserindo o nome da action e do controller na redirectToAction mais não foi...

    Segue meu Controller:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using Automacao1.Models;
    using System.Data.Entity.Infrastructure;
    
    namespace Automacao1.Controllers
    {
        public class AmbientesController : Controller
        {
            //
            // GET: /Ambientes/
    
            private AutomacaoEntities db;
    
            public AmbientesController()
            {
                db = new AutomacaoEntities();
            }
    
            public ActionResult Index()
            {
                IEnumerable<tb_ambientes> ambientes = db.tb_ambientes.OrderBy(x => x.id);
                return View(ambientes);
            }
    
            public ActionResult New()
            {
                List<tb_portas> portas = db.tb_portas.OrderBy(x => x.id).ToList();
                List<tb_ambientes> ambientes = db.tb_ambientes.OrderBy(x => x.id).ToList();
                List<tb_portas> portas_livres = new List<tb_portas>();
                List<tb_portas> portas_ambientes = null;
                bool uso = false;
    
                foreach (tb_portas porta in portas)
                {
                    uso = false;
                    foreach (tb_ambientes ambiente in ambientes)
                    {
                        portas_ambientes = ambiente.tb_portas.ToList();
                        foreach (var porta_ambiente in portas_ambientes)
                        {
                            if (porta.id == porta_ambiente.id) uso = true;
                        }
                    }
                    if (!uso) portas_livres.Add(porta);
                }
    
                return View(portas_livres);
            }
    
            [HttpPost]
            public ActionResult Adicionar(FormCollection dados)
            {
                tb_ambientes objAmbientes = new tb_ambientes();
                objAmbientes.nome = dados["nome"];
                objAmbientes.descricao = dados["descricao"];
                List<tb_portas> portas = new List<tb_portas>();
                int id_porta;
    
                for (int i = 2; i < dados.Count; i++)
                {
                    id_porta = int.Parse(dados[i]);
                    tb_portas objPorta = db.tb_portas.FirstOrDefault(x => x.id == id_porta);
                    objAmbientes.tb_portas.Add(objPorta);
                    //portas.Add(objPorta);
                }
                //objAmbientes.tb_portas = portas;
                db.tb_ambientes.Add(objAmbientes);
                db.SaveChanges();
                return RedirectToAction("Index", "Ambientes");
            }
    
            public ActionResult Edit(int id)
            {
                tb_ambientes objAmbiente;
                List<tb_portas> portas_livres = new List<tb_portas>();
    
                if (id > 0)
                {
                    objAmbiente = db.tb_ambientes.FirstOrDefault(x => x.id == id);
    
                    //Carrega as portas livres
                    List<tb_portas> portas = db.tb_portas.OrderBy(x => x.id).ToList();
                    List<tb_ambientes> ambientes = db.tb_ambientes.OrderBy(x => x.id).ToList();
                    List<tb_portas> portas_ambientes = null;
                    bool uso = false;
    
                    foreach (tb_portas porta in portas)
                    {
                        uso = false;
                        foreach (tb_ambientes ambiente in ambientes)
                        {
                            portas_ambientes = ambiente.tb_portas.ToList();
                            foreach (var porta_ambiente in portas_ambientes)
                            {
                                if (porta.id == porta_ambiente.id) uso = true;
                            }
                        }
                        if (!uso) portas_livres.Add(porta);
                    }
                }
                else
                {
                    return View();
                }
                List<Object> retorno = new List<Object>();
                retorno.Add(objAmbiente);
                retorno.Add(portas_livres);
    
                return View(retorno);
            }
    
            [HttpPost]
            public ActionResult Alterar(FormCollection dados)
            {
                int id = int.Parse(dados[0]);
                tb_ambientes objAmbiente = db.tb_ambientes.First(x => x.id == id);
                objAmbiente.nome = dados[1];
                objAmbiente.descricao = dados[2];
                List<tb_portas> porta_antiga = objAmbiente.tb_portas.ToList();
                tb_portas porta_nova;
    
                for (int i = 0; i < porta_antiga.Count; i++)
                {
                    objAmbiente.tb_portas.Remove(porta_antiga[i]);
                }
    
                for (int i = 3; i < dados.Count; i++)
                {
                    id = int.Parse(dados[i]);
                    porta_nova = db.tb_portas.First(x => x.id == id);
                    objAmbiente.tb_portas.Add(porta_nova);
                }
                db.SaveChanges();
                return RedirectToAction("Index", "Ambientes");
            }
    
            public ActionResult Deletar(int id)
            {
                tb_ambientes objAmbiente = db.tb_ambientes.First(x => x.id == id);
                db.tb_ambientes.Remove(objAmbiente);
                try
                {
                    db.SaveChanges();
                }
                catch (DbUpdateException ex)
                {
                    string mensagem = ex.ToString();
                }
                return RedirectToAction("Index", "Ambientes");
            }
        }
    }

    E minha View (Index):

    @model IEnumerable<Automacao1.Models.tb_ambientes>
    
    @{
        ViewBag.Title = "Index";
        Layout = "~/Views/Shared/_LayoutPage1.cshtml";
    }
    
    @section headers{
        <link href="~/Content/css/Geral/geral.css" rel="stylesheet" type="text/css" />
    }
    
    @section title{
        <div data-role="header" data-theme="a">
            <a href="#popupOpcoes" data-rel="popup" data-icon="gear">Opções</a>
            <h1>Ambientes</h1>
        </div>
    }
    
    <div id="janela_centro">
        <ul data-role="listview" data-inset="true" style="margin-top:50px; margin-bottom:50px;">
            @if (Model == null)
            {
                <li data-icon="plus"><a href="/Ambientes/New.html">Criar ambiente</a></li>
            } else {
                <li data-icon="plus"><a href="/Ambientes/New">Criar ambiente</a></li>
                foreach(var ambiente in Model){
                    
                    <li>
                        <a href="/Ambientes/Edit/@ambiente.id" style="width:350px;">@ambiente.nome</a>
                    </li>
                }
            }
        </ul>
    </div>
    
    @* Popup de opções *@
    <div data-role="popup" id="popupOpcoes">
    	<ul data-role="listview" data-inset="true">
            <li><a href="/Home/Index/0">Ambientes</a></li>
    	    <li><a href="/Ambientes/Index/0">Gerenciar ambientes</a></li>
    	    <li><a href="/Perfil/Index">Gerenciar perfil</a></li>
    	    <li><a href="">Sair</a></li>
        </ul>
    </div>


    • Editado Rnl Rula sexta-feira, 22 de fevereiro de 2013 17:10
    sexta-feira, 22 de fevereiro de 2013 17:09
  • Estranho cara, coloca um breakpoint em

     db.SaveChanges();

    do teu post e vai debugando para ver para onde ele vai.

    Em VB nós temos um cara chamado

    @Using Html.BeginForm()

    não tem esse cara em C#?


    Paulo Marcelo Dalbosco

    sexta-feira, 22 de fevereiro de 2013 17:23
  • Já fiz um teste colocando o breakpoint em db.SaveChanges().

    Se eu olhar no BD ele salva normalmente, mas quando ele pula para próxima linha que é a RedirectToAction ele me envia para como se fosse uma tela que ficou em cache... Como se ele não recarregasse a página e sim só desenhasse ela novamente. Tanto é que se eu colocar um breakpoint em Index() e criar um novo ambiente, o retorno da action Adicionar() deveria ser chamar a action Index(), porém, ele me envia para uma página "Index" que não está atualizada, e no debugger ele não para no breakpoint que ta na action Index(), ou seja, ele não passa pela action e não pesquisa os ambientes novamente. Agora o motivo para mim é um mistério.. :S

    sexta-feira, 22 de fevereiro de 2013 17:42
  • O "botão" que vc aperta na View para gravar os dados ele da um submit na página?

    Ou ele redireciona?

    Exemplo

    <input class="buttonLogin" type="submit" value="Confirmar"/>

    @Html.ActionLink("Cancelar", "Index", "Cliente", New With {.color = "white"})

    No input eu faço um submit e no controller do post eu redireciono ele para Idex, no segundo caso eu redireciono ele para outra View.


    Paulo Marcelo Dalbosco

    sexta-feira, 22 de fevereiro de 2013 17:53
  • Não entendi muito bem sua pergunta. A qual View você se refere?

    sexta-feira, 22 de fevereiro de 2013 17:57
  • Na View que vai mandar os dados para o Post.

    Coloca o código ae para nós tb.


    Paulo Marcelo Dalbosco

    sexta-feira, 22 de fevereiro de 2013 18:02
  • Esta que estou postando por exemplo, é o de criar ambiente..

    @using Automacao1.Models;
    
    @{
        ViewBag.Title = "Novo";
        Layout = "~/Views/Shared/_LayoutPage1.cshtml";
    }
    
    @section headers{
        <link href="~/Content/css/Geral/geral.css" rel="stylesheet" type="text/css" />
    }
    
    @section title{
        <div data-role="header" data-theme="a">
            <a href="#popupOpcoes" data-rel="popup" data-icon="gear">Opções</a>
            <h1>Criar Ambiente</h1>
        </div>
    }
    
    <div id="janela_centro">
        <form name="formNew" action="Adicionar" method="post">
            <label for="txt_nome" style="margin-top:5px;">Nome:</label>
            <input type="text" name="nome" id="txt_nome" style="margin-top:5px;"/>
            <label for="txt_descricao" style="margin-top:5px;">Descricao:</label>
        	<textarea name="descricao" id="txt_descricao" style="margin-top:5px;"></textarea>
            <fieldset data-role="controlgroup" style="margin-top:5px; margin-right:0px;">
                @foreach (var portas in Model)
                {
                    <label><input type="checkbox" name="porta_@portas.porta" value="@portas.id" /> Porta @portas.porta</label>
                }
            </fieldset>
            <input type="submit" value="Criar" />
        </form>
    </div>
    
    @* Popup de opções *@
    <div data-role="popup" id="popupOpcoes">
    	<ul data-role="listview" data-inset="true">
            <li><a href="/Home/Index/0">Ambientes</a></li>
    	    <li><a href="/Ambientes/Index">Gerenciar ambientes</a></li>
    	    <li><a href="/Perfil/Index">Gerenciar perfil</a></li>
    	    <li><a href="bmw.html">Sair</a></li>
        </ul>
    </div>

    sexta-feira, 22 de fevereiro de 2013 18:14
  • Ao invés de usar

    @using Automacao1.Models;

    Use 

    @model Automacao1.Models.SeuModel;

    e veja se dá certo.

    sexta-feira, 22 de fevereiro de 2013 18:42
  • Colocando assim:

    @model Automacao1.Models.tb_ambientes

    Ai da erro na linha:

     @foreach (var portas in Model)

    O erro é o seguinte:

    Erro de Compilação              Descrição: Erro ao compilar um recurso necessário para atender esta solicitação. Examine os detalhes específicos do erro e modifique o código fonte apropriadamente.            

    Mensagem de Erro do Compilador: CS1579: Instrução foreach não pode operar em variáveis do tipo 'Automacao1.Models.tb_ambientes' porque 'Automacao1.Models.tb_ambientes' não contém uma definição pública para 'GetEnumerator'

    sexta-feira, 22 de fevereiro de 2013 19:17