KaioMartins KaioMartins - 5 days ago 5
ASP.NET (C#) Question

Can't get a property from other class even with the navigation property configured

i'm getting a issue in my program.

In the Index View from the "Emprestimo" controller i'm trying to get the name from the book from the "Livro" class, but when i put the following it only gives me a blank space:

@Html.DisplayFor(modelItem => item.Livro.Titulo)


I Have a foreign key from "Livro" (book) inside the "Emprestimo", and when i put the following, i get the ID from the book, but far i know, i can't put a string as FK:

@Html.DisplayFor(modelItem => item.LivroId)


I tried some variations but i couldn't get the expected result. It's not a list inside the "Emprestimo", because in one loan can exist only one book.

Here's the complete code and the github link from the project if you want to take a better look:

https://github.com/KaioMartins/PersonalLibrary

Usuario.cs

namespace PersonalLibrary.Models
{
public class Usuario
{
public int UsuarioId { get; set; }

[Display(Name = "Usuário")]
public string Nome { get; set; }

[Display(Name = "E-mail")]
public string Email { get; set; }

[Display(Name = "Senha")]
public string Senha { get; set; }

public virtual List<Livro> Livros { get; set; }
public virtual List<Emprestimo> Emprestimos { get; set; }
public virtual List<Autor> Autor { get; set; }
}
}


Livro.cs

namespace PersonalLibrary.Models
{
public class Livro
{

public int LivroId { get; set; }

[Required(ErrorMessage = "Digite o nome do Livro")]
[MaxLength(60)]
[Display(Name = "Livro")]
public string Titulo { get; set; }

[Required(ErrorMessage = "Digite o ISBN")]
[MaxLength(60)]
[Display(Name = "ISBN")]
public string ISBN { get; set; }

[Required(ErrorMessage = "Digite a Data da Compra do Livro")]
[Display(Name = "Data da Compra")]
public DateTime DataCompra { get; set; }

[Display(Name = "Leitura Concluída")]
public Boolean StatusLido { get; set; }

[Required(ErrorMessage = "Cadastre um Autor antes de Cadastrar um Livro")]
[Display(Name = "Autor")]
public int AutorId { get; set; }
[ForeignKey("AutorId")]
public virtual Autor Autor { get; set; }

[Display(Name = "Usuário")]
public int UsuarioId { get; set; }
[ForeignKey("UsuarioId")]
public virtual Usuario Usuario { get; set; }

}
}


Emprestimo.cs

namespace PersonalLibrary.Models
{
public class Emprestimo
{
public int EmprestimoId { get; set; }
[Display(Name = "Emprestado")]
public Boolean Emprestado { get; set; }

[Display(Name = "Emprestado para: ")]
public string PessoaEmprestimo { get; set; }

[Display(Name = "Data do Empréstimo")]
public DateTime DataEmprestimo { get; set; }

[Display(Name = "Data da Devolução")]
public DateTime DataDevolucao { get; set; }


[Display(Name = "Livro")]
public int LivroId { get; set; }
[ForeignKey("LivroId")]
public virtual Livro Livro { get; set; }


[Display(Name = "Usuário")]
public int UsuarioId { get; set; }
[ForeignKey("UsuarioId")]
public virtual Usuario Usuario { get; set; }
}
}


EmprestimoController.cs

namespace PersonalLibrary.Controllers
{
public class EmprestimoController : Controller
{
private LibraryContext db = new LibraryContext();

// GET: Emprestimo
[AuthFilter]
public ActionResult Index()
{
using(LibraryContext ctx = new LibraryContext())
{
Usuario user = (Usuario)Session["usuario"];
int id = user.UsuarioId;

List<Emprestimo> lista = ctx.Emprestimo.Where(c => c.UsuarioId == id).ToList();
return View(lista);
}

//var emprestimo = db.Emprestimo.Include(e => e.Titulo).Include(e => e.Usuario);
//return View(emprestimo.ToList());
}

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

// GET: Emprestimo/Create
[AuthFilter]
public ActionResult Create()
{

using (LibraryContext ctx = new LibraryContext())
{
Usuario u = (Usuario)Session["usuario"];
ViewBag.LivroId = new SelectList(db.Livro.Where(c => c.UsuarioId == u.UsuarioId), "LivroId", "Titulo");
return View();
}
}

// POST: Emprestimo/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]
[AuthFilter]
public ActionResult Create([Bind(Include = "EmprestimoId,Emprestado,PessoaEmprestimo,DataEmprestimo,DataDevolucao,LivroId,UsuarioId")] Emprestimo emprestimo)
{
using (LibraryContext ctx = new LibraryContext())
{
if (ModelState.IsValid)
{
Usuario u = Session["usuario"] as Usuario;
emprestimo.UsuarioId = u.UsuarioId;

db.Emprestimo.Add(emprestimo);
db.SaveChanges();

ViewBag.LivroId = new SelectList(ctx.Usuario.Where(c => c.UsuarioId == u.UsuarioId));

return RedirectToAction("Index");
}

//ViewBag.LivroId = new SelectList(db.Livro, "LivroId", "Titulo", emprestimo.LivroId);

return View(emprestimo);
}
}

// GET: Emprestimo/Edit/5
[AuthFilter]
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Emprestimo emprestimo = db.Emprestimo.Find(id);
if (emprestimo == null)
{
return HttpNotFound();
}

using (LibraryContext ctx = new LibraryContext())
{
Usuario u = (Usuario)Session["usuario"];
ViewBag.LivroId = new SelectList(db.Livro.Where(c => c.UsuarioId == u.UsuarioId), "LivroId", "Titulo");
return View(emprestimo);
}
//ViewBag.LivroId = new SelectList(db.Livro, "LivroId", "Titulo", emprestimo.LivroId);
//ViewBag.UsuarioId = new SelectList(db.Usuario, "UsuarioId", "Nome", emprestimo.UsuarioId);
//return View(emprestimo);
}

// POST: Emprestimo/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]
[AuthFilter]
public ActionResult Edit([Bind(Include = "EmprestimoId,Emprestado,PessoaEmprestimo,DataEmprestimo,DataDevolucao,LivroId,UsuarioId")] Emprestimo emprestimo)
{
if (ModelState.IsValid)
{
Usuario u = Session["usuario"] as Usuario;
emprestimo.UsuarioId = u.UsuarioId;

db.Entry(emprestimo).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.LivroId = new SelectList(db.Livro, "LivroId", "Titulo", emprestimo.LivroId);
ViewBag.UsuarioId = new SelectList(db.Usuario, "UsuarioId", "Nome", emprestimo.UsuarioId);
return View(emprestimo);
}

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

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

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


Index.cshtml (Emprestimo)

@model IEnumerable<PersonalLibrary.Models.Emprestimo>

@{
ViewBag.Title = "Livros Emprestados";
}

<p>
@Html.ActionLink("Cadastrar Empréstimo", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.Livro.Titulo)
</th>

<th>
@Html.DisplayNameFor(model => model.Emprestado)
</th>
<th>
@Html.DisplayNameFor(model => model.PessoaEmprestimo)
</th>
<th>
@Html.DisplayNameFor(model => model.DataEmprestimo)
</th>
<th>
@Html.DisplayNameFor(model => model.DataDevolucao)
</th>
<th></th>
</tr>

@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.LivroId)
</td>

<td>
@Html.DisplayFor(modelItem => item.Emprestado)
</td>
<td>
@Html.DisplayFor(modelItem => item.PessoaEmprestimo)
</td>
<td>
@Html.DisplayFor(modelItem => item.DataEmprestimo)
</td>
<td>
@Html.DisplayFor(modelItem => item.DataDevolucao)
</td>
<td>
@Html.ActionLink("Editar", "Edit", new { id=item.EmprestimoId }) |
@Html.ActionLink("Detalhes", "Details", new { id=item.EmprestimoId }) |
@Html.ActionLink("Excluir", "Delete", new { id=item.EmprestimoId })
</td>
</tr>
}

</table>

Answer

That is because the Livro property is virtual, therefore it will not be loaded unless you access the property or load it like this:

List<Emprestimo> lista = ctx.Emprestimo.Include(x => x.Livro).Where(c => c.UsuarioId == id).ToList();

This is called eager loading. By default EF is configured for lazy loading.

Comments