EntityFramework和Lazy Loading

时间:2014-01-22 06:31:05

标签: 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; 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; }

}

和:

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

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

using (var newContext = new MyDbContext())

    {
        var selectedPerson = newContext.Persons.ToList();  
    }

但是,当我运行我的项目时,我得到的PhoneNumber为空! 我想如果我在我的导航属性中添加“虚拟”关键字,那么我也会得到PhoneNumber。 我弄错了?

3 个答案:

答案 0 :(得分:2)

我找到了解决方案,我应该将public修饰符添加到我的对象类中:

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

答案 1 :(得分:0)

首先:我不知道这是否有所不同,但我已将导航属性配置为List<T>并且延迟加载有效。

也许使用ICollection<T> EF不会初始化这些集合,因为它不知道要使用哪种具体列表类型(只是猜测)

 public virtual List<PhoneNumber> PhoneNumbers { get; set; }

第二:默认情况下,您不必明确配置某些内容,它应该是开箱即用的。无论如何,请确保您不要停用LazyLoadingEnabledProxyCreationEnabled

第三:自EF5 with Framework 4.5以来支持枚举数据类型(如果仍然运行Framework 4.0,则应将其phoneType设置为int

答案 2 :(得分:0)

您的代码

using (var newContext = new MyDbContext())
{
    var selectedPerson = newContext.Persons.ToList();  
}

永远不会加载PhoneNumbers(或任何导航属性),因为您没有Include它们。在语句运行之后,上下文被释放,因此任何延迟加载尝试都会抛出异常。

所以(假设您没有通过设置LazyLoadingEnabledProxyCreationEnabled = false来禁用上下文中的延迟加载。)您应该包含PhoneNumbers

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

或在上下文的生命周期内处理某个人的PhoneNumbers集合。 (这将执行其他SQL查询)。