即使配置了导航属性,也无法从其他类获取属性



我在程序中遇到问题。

在" emprestimo"控制器的索引视图中,我试图从" livro"类获取名称,但是当我放置以下内容时,它只会给我一个空白:

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

我在" Emprestimo"中有一个来自" Livro"(book)的外键,当我放置以下内容时,我从书中获得ID,但我知道,我无法将字符串作为fk:

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

我尝试了一些变体,但无法获得预期的结果。这不是" Emprestimo"中的列表,因为一笔贷款只能存在一本书。

如果您想更好地查看,这是项目的完整代码和GitHub链接:

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>

这是因为Livro属性是虚拟的,因此,除非您访问属性或这样的加载,否则不会加载它:

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

这称为急切的加载。默认情况下,EF配置为懒惰加载。

在您的emprestimo.edit控制器动作上尝试加载livro实体:

Emprestimo emprestimo = db.Emprestimo.Find(id);
if (emprestimo == null)
{
   return HttpNotFound();
}
db.Entry(emprestimo).Reference(e => e.Livro).Load(); 

在旁注上,您也不需要创建新的上下文来获取Livros列表,您已经拥有一个非常好的上下文(DB)。因此,而不是:

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);
}

只是做:

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

,您实际上在任何地方都不需要这个新上下文,只需使用" db"一个。

最新更新