Marcelo,
Refiz a modelagem de usuários, me guiando pelo exemplo do CaelumEstoque - essa parte ficou show de bola!
A parte do cadastro de estoque - ficou bem mais simples e muito estável. Tanto o login quanto o cadastro de estoque, ficaram show de bola. Funcionando super bem.
Agora vamos para a 3ª e última tela deste meu exemplo.
A tela de Áreas, onde eu tenho um combobox.
1) já consigo gravar (inserir) na tabela,
2) excluir na tabela e consultar.
Meu problema é no EDITAR.
Já estou identificando outras limitações tb, exempo:
1) no login, eu gostaria de exibir uma mensagem na tela, por uma viewbag por exemplo, mas não descobri como fazer. Não exibe a mensagem.
2) se eu excluir uma escola que tem uma área, deveria dar a mensagem em tela da validation annotation, mas tb ainda não acertei fazer.
MAS... vamos para o EDITAR para eu conseguir fechar essas tres telas. :D
Seguem os meus códigos.
O modelo ficou assim:
public class Area
{
public int AreaId { get; set; }
public string Nome { get; set; }
public int EscolaId { get; set; }
public virtual Escola Escolas { get; set; }
}
public class Escola
{
public Escola ()
{
Areas = new List<Area>();
}
public int EscolaId { get; set; }
public string Nome { get; set; }
public int UsuarioId { get; set; }
public virtual Usuario Usuarios { get; set; }
public virtual ICollection<Area> Areas { get; set; }
}
public class Usuario
{
public Usuario()
{
Escolas = new List<Escola>();
}
public int UsuarioId { get; set; }
public string Nome { get; set; }
[EmailAddress]
public string Email { get; set; }
public string Senha { get; set; }
public virtual ICollection<Escola> Escolas { get; set; }
}
Meus "Map" de Area (Fluent Api)
public AreaMap()
{
ToTable("Area");
HasKey(x => x.AreaId);
Property(x => x.AreaId)
.HasColumnName("AreaId")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(x => x.Nome).IsRequired().HasMaxLength(50)
.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute { IsUnique = true }));
//S3: A chave estrangeira para a tabela Area - EscolaId
HasRequired(c => c.Escolas)
.WithMany(p => p.Areas).HasForeignKey(p => p.EscolaId);
}
Meu Controller de Area:
[AutorizacaoFilter]
public class AreaController : Controller
{
private AreaDAO dao;
private EscolaDAO daoEscola;
public AreaController()
{
this.dao = new AreaDAO();
this.daoEscola = new EscolaDAO();
}
// GET: Area
public ActionResult Index()
{
IList<Area> area = dao.Lista();
return View(area);
}
// GET: Area/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Area area = dao.BuscarPorId(id);
ViewBag.Escolas = daoEscola.Lista();
if (area == null)
{
return HttpNotFound();
}
return View(area);
}
// GET: Area/Create
public ActionResult Create()
{
ViewBag.Escolas = daoEscola.Lista();
return View();
}
// POST: Area/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 = "AreaId,Nome")]*/ Area area)
{
if (ModelState.IsValid)
{
dao.Adiciona(area);
return RedirectToAction("Index");
}
return View(area);
}
// GET: Area/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Area area = dao.BuscarPorId(id);
ViewBag.Escolas = daoEscola.Lista();
if (area == null)
{
return HttpNotFound();
}
return View(area);
}
// POST: Area/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 = "AreaId,Nome")]*/ Area area)
{
if (ModelState.IsValid)
{
dao.Atualiza(area);
return RedirectToAction("Index");
}
return View(area);
}
// GET: Area/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Area area = dao.BuscarPorId(id);
if (area == null)
{
return HttpNotFound();
}
return View(area);
}
// POST: Area/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Area area = dao.BuscarPorId(id);
dao.Remove(area);
return RedirectToAction("Index");
}
}
View de Area:
@model EscolaWeb.Models.Area
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Area</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.AreaId)
<div class="form-group">
@Html.LabelFor(model => model.Nome, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Nome, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Nome, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<label for="escola" class="control-label col-md-2">Escola:</label>
<div class="col-md-8">
<select id="escola" name="area.EscolaId" class="form-control">
@foreach (var escola in ViewBag.Escolas)
{
<option value="@escola.EscolaId" selected="@escola.EscolaId.Equals(Model.EscolaId)">
@escola.Nome
</option>
}
</select>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>