16

考虑PersonAddress类定义为

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; }
}

其中只有一些人有一个地址,但所有地址都有一个人。这是一对零或一的关系,所以我将其配置为

modelBuilder.Entity<Address>()
  .HasKey(a => a.PersonId)
  .HasRequired(a => a.Person)
  .WithOptional(a => a.Address);

现在,在我的代码中,以下方法(急切加载)工作得非常好。

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

但是,以下方法(延迟加载)没有。

var person = context.Person
  .Single(a => a.PersonId == 123);
var address = person.Address; // address == null (incorrect)

此外,我连接了 SQL Profiler,我可以看到 EF 在第二种情况下甚至没有尝试延迟加载地址——它只是返回 null。

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

我使用 Entity Framework 5 和 Entity Framework 6 Alpha 3 对此进行了测试,并获得了相同的结果。

4

4 回答 4

24

我想出了这个。实体类必须声明为public和延迟加载的属性public virtual才能工作。IE

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; }
}
于 2013-05-08T15:15:01.827 回答
1

有时也可能是原因的另一点是,如果忘记将虚拟修饰符添加到导航属性

于 2014-01-23T22:24:57.120 回答
1

有一些规则可以启用或延迟加载:

context.Configuration.ProxyCreationEnabled should be true.
context.Configuration.LazyLoadingEnabled should be true.

导航属性应定义为公共的、虚拟的。

如果属性未定义为虚拟,则上下文不会进行延迟加载。

例子

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext() : base("ProjectConnection")
    {
        Configuration.LazyLoadingEnabled = true;
        Configuration.ProxyCreationEnabled = true;
    }

}

阅读更多

于 2018-05-13T11:49:47.990 回答
0

如果您使用的是数据库优先方法,请确保延迟加载启用属性为 True。您可以在 EDMX 图表的属性中找到此属性。

您还可以通过设置 dbcontext.Configuration.LazyLoadingEnabled = true dbcontext 是 DbContext 的实例来覆盖该行为。

于 2014-05-23T09:17:06.917 回答