Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Dados de Foreign Key não aparecem da Edição e Exclusão

Criei dois modelos. Um auxiliar de Cidades que chamei de xCidades e outro de Contatos que tem um atributo cidade:

public class xCidades
    {
        [Key]
        public int CidadeId { get; set; }

        [Required, StringLength(30)]
        public string Cidade { get; set; }

        [Required]
        public xEstados Estado { get; set; }
    }
public class Contatos
    {
        [Key]
        public int ContatoId { get; set;}

        [Required, StringLength(30)]
        public string Contato   { get; set;}

        [StringLength(50)]
        public string Endereco  { get; set;}

        [StringLength(30)]
        public string Bairro { get; set; }

        public int CidadeId  { get; set;}
        public xCidades Cidade { get; set; }

        [StringLength(9)]
        public string CEP  { get; set;}

        [Required, EmailAddress]
        [DataType(DataType.EmailAddress)]
        public string Email  { get; set;}

        [StringLength(15)]
        [DataType(DataType.PhoneNumber)]
        public string Fone_Celular  { get; set;}

        [StringLength(15)]
        [DataType(DataType.PhoneNumber)]
        public string Fone_Fixo  { get; set;}
    }

Com eles usei o Scaffold para gerar os controllers e views respectivos:

public class xCidadesController : Controller
    {
        private ApplicationDbContext db = new ApplicationDbContext();

        // GET: xCidades
        public ActionResult Index()
        {
            return View(db.xCidades.ToList());
        }

        // GET: xCidades/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            xCidades xCidades = db.xCidades.Find(id);
            if (xCidades == null)
            {
                return HttpNotFound();
            }
            return View(xCidades);
        }

        // GET: xCidades/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: xCidades/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "CidadeId,Cidade,Estado")] xCidades xCidades)
        {
            if (ModelState.IsValid)
            {
                db.xCidades.Add(xCidades);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(xCidades);
        }

        // GET: xCidades/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            xCidades xCidades = db.xCidades.Find(id);
            if (xCidades == null)
            {
                return HttpNotFound();
            }
            return View(xCidades);
        }

        // POST: xCidades/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "CidadeId,Cidade,Estado")] xCidades xCidades)
        {
            if (ModelState.IsValid)
            {
                db.Entry(xCidades).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(xCidades);
        }

        // GET: xCidades/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            xCidades xCidades = db.xCidades.Find(id);
            if (xCidades == null)
            {
                return HttpNotFound();
            }
            return View(xCidades);
        }

        // POST: xCidades/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            xCidades xCidades = db.xCidades.Find(id);
            db.xCidades.Remove(xCidades);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
public class ContatosController : Controller
    {
        private ApplicationDbContext db = new ApplicationDbContext();

        // GET: Contatos
        public ActionResult Index()
        {
            var contatos = db.Contatos.Include(c => c.Cidade);
            return View(contatos.ToList());
        }

        // GET: Contatos/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Contatos contatos = db.Contatos.Find(id);
            if (contatos == null)
            {
                return HttpNotFound();
            }
            return View(contatos);
        }

        // GET: Contatos/Create
        public ActionResult Create()
        {
            ViewBag.CidadeId = new SelectList(db.xCidades, "CidadeId", "Cidade");
            return View();
        }

        // POST: Contatos/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "ContatoId,Contato,Endereco,Bairro,CidadeId,CEP,Email,Fone_Celular,Fone_Fixo")] Contatos contatos)
        {
            if (ModelState.IsValid)
            {
                db.Contatos.Add(contatos);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            ViewBag.CidadeId = new SelectList(db.xCidades, "CidadeId", "Cidade", contatos.CidadeId);
            return View(contatos);
        }

        // GET: Contatos/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Contatos contatos = db.Contatos.Find(id);
            if (contatos == null)
            {
                return HttpNotFound();
            }
            ViewBag.CidadeId = new SelectList(db.xCidades, "CidadeId", "Cidade", contatos.CidadeId);
            return View(contatos);
        }

        // POST: Contatos/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "ContatoId,Contato,Endereco,Bairro,CidadeId,CEP,Email,Fone_Celular,Fone_Fixo")] Contatos contatos)
        {
            if (ModelState.IsValid)
            {
                db.Entry(contatos).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.CidadeId = new SelectList(db.xCidades, "CidadeId", "Cidade", contatos.CidadeId);
            return View(contatos);
        }

        // GET: Contatos/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Contatos contatos = db.Contatos.Find(id);
            if (contatos == null)
            {
                return HttpNotFound();
            }
            return View(contatos);
        }

        // POST: Contatos/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Contatos contatos = db.Contatos.Find(id);
            db.Contatos.Remove(contatos);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }

E as Views também foram geradas e funcionam perfeitamente na listagem (Index), Cadastro (Create) , Exclusão (Delete) e Alteração (Edit)

O único problema é que nas views de Detalhe (Details) e Exclusão (Delete) dos Contatos, o nome da Cidade não aparece. Em ambas, o nome da Cidade é um campo fixo.

Veja que na tela de listagem (Index) o nome da Cidade do contato também é um texto fixo e aparece perfeitamente.

Vou colocar as View Index (Que mostra o nome da Cidade) e a View Details (que não mostra)

@model IEnumerable<Projeto.Models.Contatos>

@{
    ViewBag.Title = "Contatos";
}

<h2>Lista geral resumida</h2>

<p>
    @Html.ActionLink("Criar novo contato", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Contato)
        </th>
        <!--th>
            @Html.DisplayNameFor(model => model.Endereco)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Bairro)
        </th-->
        <th>
            @Html.DisplayNameFor(model => model.Cidade.Cidade)
        </th>
        <!--th>
            @Html.DisplayNameFor(model => model.CEP)
        </th-->
        <th>
            @Html.DisplayNameFor(model => model.Email)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Fone_Celular)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Fone_Fixo)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Contato)
        </td>
        <!--td>
            @Html.DisplayFor(modelItem => item.Endereco)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Bairro)
        </td-->
        <td>
            @Html.DisplayFor(modelItem => item.Cidade.Cidade)
        </td>
        <!--td>
            @Html.DisplayFor(modelItem => item.CEP)
        </td-->
        <td>
            @Html.DisplayFor(modelItem => item.Email)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Fone_Celular)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Fone_Fixo)
        </td>
        <td>
            @Html.ActionLink("Alterar", "Edit", new { id=item.ContatoId }) |
            @Html.ActionLink("Detalhes", "Details", new { id=item.ContatoId }) |
            @Html.ActionLink("Excluir", "Delete", new { id=item.ContatoId })
        </td>
    </tr>
}

</table>
@model Projeto.Models.Contatos

@{
    ViewBag.Title = "Contatos";
}

<h2>Detalhe</h2>

<div>
    <h4>Contato</h4>
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.Contato)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Contato)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Endereco)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Endereco)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Bairro)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Bairro)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Cidade.Cidade)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Cidade.Cidade)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.CEP)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.CEP)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Email)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Email)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Fone_Celular)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Fone_Celular)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Fone_Fixo)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Fone_Fixo)
        </dd>

    </dl>
</div>
<p>
    @Html.ActionLink("Alterar", "Edit", new { id = Model.ContatoId }) |
    @Html.ActionLink("Voltar a lista resumo", "Index")
</p>
1 resposta
solução!

Olá Jaqueline,

provavelmente o problema é que o seu método db.Contatos.Find(id) no hora de visualizar o Contatos está fazendo um Lazy Load. No modo lazy load, quando o Entity faz uma busca no banco ele não preenche propriedades referentes a relações com outros modelos. Ou seja, no caso ele trouxe contatos mas não populou a sua propriedade xCidades Cidade. O que você pode fazer é fazer um Eagerly Loading, que força o Entity a preencher mesmo as propriedades referentes aos relacionamentos.

Para isto, você precisa entrar no Find e quando for buscar o Contatos no context, chamar o método .Include() para a propriedade Cidade. Neste link ele mostra um exemplo de como faz.