在Razor View中显示相关的DB值:NullReferenceException

时间:2012-12-14 19:22:05

标签: asp.net-mvc entity-framework razor

我有4个相关的表:Project-> ProjectDoc-> Comment-> CommentReply&用户 其中3个表与用户有关。当我尝试获取User.FirstName值时,它给出了异常,表明:

Object reference not set to an instance of an object.

首先是用户模型。

public class User
{
    public int UserID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public virtual ICollection<Comment> Comment { get; set; }
    public virtual ICollection<CommentReply> CommentReply { get; set; }
    public virtual ICollection<Project> Project { get; set; }
}

现在是项目模型。

public class Project
{
    public int ProjectID { get; set; }
    public int UserID { get; set; }
    public string Title { get; set; }
    public virtual ICollection<ProjectDoc> ProjectDoc { get; set; }
    public User User { get; set; }
}

现在是Razor View。我已经标注了例外情况。

@Model.User.FirstName   //exception

@foreach (var doc in Model.ProjectDoc)
{
    @doc.DocTitle
    <br />  
       <div>
           @doc.Comment.Count() comments
       </div>
   foreach (var comment in doc.Comment)
   { 
       <div>
        @comment.CommentVote.Count() 
        votes
        @comment.UserID - user ID<br />

        @comment.User.FirstName  //exception
        @comment.Text
       </div>
       <br />
       foreach (var creply in comment.CommentReply)
       {

          @creply.User.FirstName   //exception
          <br />
          @creply.Text
          <br />
       }
   }
}

如果我删除User.FirstName行,那么它可以正常工作。我需要更改什么来获取FirstName值?您需要更多信息来帮助吗?

更新:我的控制器,如果它有帮助。

    // GET: /Projects/Details/5

    public ActionResult Details(int id = 0)
    {
        Project project = db.Projects.Find(id);
        if (project == null)
        {
            return HttpNotFound();
        }
        return View(project);
    }

我尝试将控制器更改为此,但无法正常工作

      Project project = db.Projects
          .Include(i => i.User)
          .SingleOrDefault(x => x.ProjectID == id);

更新2 :Fluent API映射问题?

UserID字段有一个值,但User_UserID值为NULL,所以我假设我正在进行流畅的api映射(我不想要User_UserID列)。

 modelBuilder.Entity<User>()
      .HasMany(p => p.Project)
      .WithRequired()
      .HasForeignKey(c => c.UserID)
      .WillCascadeOnDelete(false);

是否导致问题?

2 个答案:

答案 0 :(得分:1)

我想你想使用实体的延迟加载...为了使其工作,必须将导航属性标记为虚拟,因此EF可以在必要时使用代理类来加载数据。

在您的模型中,User类中的Project属性未标记为虚拟,因此延迟加载不起作用。

您可以将User属性设为虚拟,也可以使用Include method加载数据而不进行延迟加载。

答案 1 :(得分:0)

关于延迟加载的注意事项......据我所知,您只是从数据库中获取ProjectDoc列表。然后查看每个ProjectDoc,对于每个文档,您使用导航属性(@ doc.Comment),然后对每个注释进行注释回复。

如果我没有误会,那么每一个电话都会打到数据库。您可能需要考虑在一个查询中提取所需的所有数据,而不是为每个项目命中数据库。

查看n+1 select problem