我有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);
是否导致问题?
答案 0 :(得分:1)
我想你想使用实体的延迟加载...为了使其工作,必须将导航属性标记为虚拟,因此EF可以在必要时使用代理类来加载数据。
在您的模型中,User
类中的Project
属性未标记为虚拟,因此延迟加载不起作用。
您可以将User
属性设为虚拟,也可以使用Include
method加载数据而不进行延迟加载。
答案 1 :(得分:0)
关于延迟加载的注意事项......据我所知,您只是从数据库中获取ProjectDoc列表。然后查看每个ProjectDoc,对于每个文档,您使用导航属性(@ doc.Comment),然后对每个注释进行注释回复。
如果我没有误会,那么每一个电话都会打到数据库。您可能需要考虑在一个查询中提取所需的所有数据,而不是为每个项目命中数据库。