0

我有 4 个相关表:Project->ProjectDoc->Comment->CommentReply & Users 其中 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; }
}

现在是剃刀视图。我已经标记了例外情况。

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

这是造成问题的原因吗?

4

2 回答 2

1

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

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

您可以将User属性设为虚拟或使用该Include 方法加载数据而不进行延迟加载。

于 2012-12-14T20:01:15.207 回答
0

请注意延迟加载...据我所知,您只是从数据库中获取 ProjectDoc 列表。然后,您查看每个 ProjectDoc,对于每个文档,您正在使用导航属性 (@doc.Comment),然后对于每个评论,您都通过评论回复。

如果我没记错的话,这些调用中的每一个都在访问数据库。您可能需要考虑在一个查询中提取您需要的所有数据,而不是为每个项目访问数据库。

看看n+1 选择问题

于 2012-12-14T22:07:59.437 回答