我有这个简单的模型:
class Parent
{
public int Id { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public virtual Parent Parent { get; set; }
}
class MyContext : DbContext
{
public DbSet<Parent> Parents { get; set; }
public DbSet<Child> Children { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Child>().HasRequired(s => s.Parent).WithMany(s => s.Children).HasForeignKey(s => s.ParentId);
base.OnModelCreating(modelBuilder);
}
}
当我使用MyContext
如下所示时,我得到空引用异常,因为child.Parent
为空
var context = new MyContext();
var child = context.Children.First();
var parentId = child.Parent.Id; // Parent == null
要解决此问题,我必须将Parent
和Child
类的访问修饰符更改为public
。
为什么需要?或者这只是一个错误?
答案 0 :(得分:5)
这不是一个错误,您正在使用名为Lazy Loading的实体框架功能,要使用它,您需要满足在此link中可以找到的一些要求。其中一个要求是您的实体类必须是public
。在该链接中,您将找到正确的解释,说明为什么您应该满足这些要求,但总的来说,您的问题是因为EF无法从您的实体创建代理类,因为您无法使用延迟加载。您已经满足了延迟加载的主要要求,导航属性必须是virtual
,但首先您必须满足EF创建代理类所需的要求。
作为附加资源,我建议您查看此msdn页面,您可以在其中找到使用EF加载相关实体的所有方法。
答案 1 :(得分:2)
首先,要清除一些内容:您的课程不是<div class="table">
<div class="td">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ut libero et odio rhoncus luctus a a nunc. Etiam et dolor magna. Vivamus semper mi in porta pellentesque.
</div>
<div class="td">
<img alt="" src="http://placehold.it/120x148" style="width: 120px; height: 148px;" />
</div>
</div>
,而是private
。您不能将顶级类型(非嵌套类型)声明为私有类型(有关详细信息,请参阅MSDN Access Modifiers)。
其次,默认情况下,首先启用延迟加载代码。正如octaviocci所提到的,如果你期望使用Lazy Loading,你需要公开它们:它只是要求的一部分。通过将导航属性声明为internal
,您告诉EF您希望使用延迟加载。如果您不想,可以(应该)删除virtual
关键字。然后,在获取实体时,使用virtual
方法急切地加载相关实体。
Include