C# EntityFramework与延迟加载

C# EntityFramework与延迟加载,c#,entity-framework,C#,Entity Framework,我有两个对象类 class Person { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set;} public DateTime BirthDate { get; set; } public bool IsMale { get; set; } public byte[] Image { get;

我有两个对象类

 class Person
{

    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set;}
    public DateTime BirthDate { get; set; }
    public bool IsMale { get; set; }
    public byte[] Image { get; set; }
    public byte[] RowVersion { get; set; }
    public virtual Person Parent { get; set; }
    public virtual ICollection<PhoneNumber> PhoneNumber { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
    public virtual  PersonInfo PersonInfo { get; set; }

}
我在导航属性中添加了“virtual”关键字以启用懒散加载,然后添加了一些代码以获取人员列表:

using (var newContext = new MyDbContext())

    {
        var selectedPerson = newContext.Persons.ToList();  
    }
但是,当我运行我的项目时,我得到的电话号码是空的! 我想如果我在导航属性中添加“virtual”关键字,那么我也会得到电话号码。。
我完全弄错了?

首先:我不知道这是否有什么区别,但我已经将导航属性配置为
列表,并且延迟加载可以工作

可能使用
ICollection
EF不会初始化这些集合,因为它不知道使用哪种具体的列表类型(只是猜测)

公共虚拟列表电话号码{get;set;}
第二:默认情况下,您不必显式地配置某些东西,它应该是开箱即用的。无论如何,请确保不禁用
LazyLoadingEnabled
ProxyCreationEnabled

第三:从EF5开始,框架4.5就支持枚举数据类型(如果仍然运行框架4.0,则应将其
phoneType
设置为int

您的代码)

using (var newContext = new MyDbContext())
{
    var selectedPerson = newContext.Persons.ToList();  
}
不会加载
电话号码
(或任何导航属性),因为您没有
包含它们。并且在语句运行后,上下文将被释放,因此任何延迟加载尝试都将引发异常

因此(假设您没有通过设置
LazyLoadingEnabled
ProxyCreationEnabled
=false来禁用上下文中的延迟加载)。您应该包括
电话号码

var selectedPerson = newContext.Persons.Include(p => p.PhoneNumbers).ToList();

或者在上下文的生命周期内寻址一个人的
电话号码
集合。(这将执行额外的SQL查询)。

我找到了解决方案,我应该在我的对象类中添加公共修饰符,以便:

 Public class Person
  {

     public int Id { get; set; }
     public string FirstName { get; set; }
     public string LastName { get; set;}
     public DateTime BirthDate { get; set; }
     public bool IsMale { get; set; }
     public byte[] Image { get; set; }
     public byte[] RowVersion { get; set; }
     public virtual Person Parent { get; set; }
     public virtual ICollection<PhoneNumber> PhoneNumber { get; set; }
     public virtual ICollection<Address> Addresses { get; set; }
     public virtual  PersonInfo PersonInfo { get; set; }

  }

你打开惰性加载了吗?我想如果我加上“虚拟”就足够了关键词到我的导航关键词,如:个人和电话号码!!!是的,你这么认为,但它不是。确保你有
newContext.Configuration.LazyLoadingEnabled
等于
true
@SergeyBerezovskiy,我做到了,但它不起作用!!谢谢..EntityFramework5中默认启用了延迟加载和代理吗?是的,我这么认为。我从来没有这样做过在我的配置中显式地设置这些值,它就会工作。您可以使用
var person=context.Persons.Find(1);
现在检查person.GetType().Name-它应该类似于
System.Data.Entity.DynamicProxies.Person_ABCBE0D1022D01EB84B81873D49DEEC60879FC4152BB115C3EC16FB8003A
和Person.phoneNumber应该是空列表,即使没有相关记录可用。我认为添加“虚拟”就足够了对于我的导航属性,在您的代码中,您需要这样的内容:Person Join with Phone,因此您显式地进行加载,这不是延迟加载。不,这不是延迟加载,但我还指出了延迟加载成功的条件。
var selectedPerson = newContext.Persons.Include(p => p.PhoneNumbers).ToList();
 Public class Person
  {

     public int Id { get; set; }
     public string FirstName { get; set; }
     public string LastName { get; set;}
     public DateTime BirthDate { get; set; }
     public bool IsMale { get; set; }
     public byte[] Image { get; set; }
     public byte[] RowVersion { get; set; }
     public virtual Person Parent { get; set; }
     public virtual ICollection<PhoneNumber> PhoneNumber { get; set; }
     public virtual ICollection<Address> Addresses { get; set; }
     public virtual  PersonInfo PersonInfo { get; set; }

  }
 Public class PhoneNumber
  {

    public enum PhoneType
    { Work, Mobile, Home };

     public int id { get; set; }
     public string phoneNumber { get; set; }
     public PhoneType phoneType { get; set; }
     public virtual Person Person { get; set; }
  }