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

时间:2016-11-26 20:07:50

标签: c# asp.net

我的程序中出现问题。

在“Emprestimo”控制器的索引视图中,我试图从“Livro”类中获取书中的名称,但是当我把它放在下面时它只给我一个空白区域:

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

我在“Emprestimo”中有一个来自“Livro”(书)的外键,当我放下以下内容时,我从书中得到了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>

2 个答案:

答案 0 :(得分:0)

在您的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”。

答案 1 :(得分:0)

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

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

这称为急切加载。默认情况下,EF配置为延迟加载。