考虑定义为
的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; }
}
其中只有一些人拥有地址,但所有地址都有人。这是one-to-zero-or-one relationship,因此我将其配置为
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事件探查器,我可以看到EF在第二种情况下甚至没有尝试延迟加载地址 - 它只返回null。
我无法找到任何说明EF不会延迟加载一对一或一个导航属性的文档。这是设计,是一个错误,还是我做错了什么?
我使用Entity Framework 5和Entity Framework 6 Alpha 3测试了这一点并获得了相同的结果。
答案 0 :(得分: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; }
}
答案 1 :(得分:1)
有时可能也是原因的另一点是,如果忘记将虚拟修改器添加到导航属性
答案 2 :(得分:1)
有一些规则要启用或延迟加载:
context.Configuration.ProxyCreationEnabled should be true.
context.Configuration.LazyLoadingEnabled should be true.
导航属性应定义为public,virtual。
如果属性未定义为虚拟,则上下文不会进行延迟加载。
示例强>
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext() : base("ProjectConnection")
{
Configuration.LazyLoadingEnabled = true;
Configuration.ProxyCreationEnabled = true;
}
}
答案 3 :(得分:0)
如果您使用的是数据库优先方法,请确保Lazy Loading Enabled属性为True。您可以在EDMX图的属性中找到此属性。
您还可以通过设置覆盖行为
dbcontext.Configuration.LazyLoadingEnabled = true
其中dbcontext是DbContext的实例。