在实体框架中,为什么延迟加载不适用于一对一或一个导航属性?

Mik*_*ike 16 entity-framework lazy-loading ef-code-first entity-framework-5 entity-framework-6

考虑Person和Address定义为的类

class Person
{
  public int PersonId { get; set; }
  public virtual Address Address { get; set; }
}

class Address
{
  public int PersonId { get; set; }
  public virtual Person Person { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

只有一些人有一个地址,但所有地址都有一个人.这是一对一或零关系,因此我将其配置为

modelBuilder.Entity<Address>()
  .HasKey(a => a.PersonId)
  .HasRequired(a => a.Person)
  .WithOptional(a => a.Address);
Run Code Online (Sandbox Code Playgroud)

现在,在我的代码中,以下方法(急切加载)完美地运行.

var person = context.Person
  .Include(a => a.Address)
  .Single(a => a.PersonId == 123);
var address = person.Address; // address != null (correct)
Run Code Online (Sandbox Code Playgroud)

但是,以下方法(延迟加载)不会.

var person = context.Person
  .Single(a => a.PersonId == 123);
var address = person.Address; // address == null (incorrect)
Run Code Online (Sandbox Code Playgroud)

此外,我连接了SQL事件探查器,我可以看到EF甚至没有尝试在第二种情况下延迟加载地址 - 它只返回null.

我一直无法找到任何说明EF不会延迟加载一对一或一个导航属性的文档.这是设计,是一个错误,还是我做错了什么?

我使用Entity Framework 5和Entity Framework 6 Alpha 3测试了这一点并获得了相同的结果.

Mik*_*ike 23

我想出了这一个.必须将实体类声明为延迟加载public的属性public virtual才能工作.即

public class Person
{
  public int PersonId { get; set; }
  public virtual Address Address { get; set; }
}

public class Address
{
  public int PersonId { get; set; }
  public virtual Person Person { get; set; }
}
Run Code Online (Sandbox Code Playgroud)