繁体   English   中英

EF6延迟加载不起作用,而快速加载可以正常工作

[英]EF6 lazy loading doesn't work while eager loading works fine

我将应用程序从EF4.1更新到EF6,现在出现了延迟加载问题。 我使用EF6.x DbContext Generator生成新的DbContext。 所有的这个建议的文章也适用。

  • 我的课是公开的
  • 不密封,不抽象
  • 有一个公共的建设者
  • 不要同时实现IEntityWithChangeTrackerIEntityWithRelationships
  • 无论ProxyCreationEnabledLazyLoadingEnabled设置为true
  • 导航属性是虚拟的

对我来说,看起来还很奇怪的是,如果我在Include("...")明确包含了导航属性,它将被加载。

我的POCO和DbContext的简化版本:

public partial class Ideation
{
    public Ideation()
    {

    }

    public long Id { get; set; }
    public Nullable<long> ChallengeId { get; set; }

    public virtual Challenge Challenge { get; set; }
}

public partial class Challenge
{
    public Challenge()
    {
        this.Ideations = new HashSet<Ideation>();
    }

    public long Id { get; set; }

    public virtual ICollection<Ideation> Ideations { get; set; }
}

public partial class BoxEntities : DbContext
{
    public TIBoxEntities()
        : base("name=BoxEntities")
    {

    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public virtual DbSet<Ideation> Ideations { get; set; }
    public virtual DbSet<Challenge> Challenges { get; set; }
}

我也试图设置ProxyCreationEnabledLazyLoadingEnabled明确无没有运气。 该调试会话屏幕快照显示该实体未作为动态代理加载:

除错

我还想念什么?

可能发生的情况是,您尝试使用Find加载的实体已作为非代理对象附加到上下文。 例如:

using (var context = new MyContext())
{
    var ideation = new Ideation { Id = 1 }; // this is NOT a proxy
    context.Ideations.Attach(ideation);

    // other stuff maybe ...

    var anotherIdeation = context.Ideations.Find(1);
}

anotherIdeation将是已经连接的非代理,并且不能进行延迟加载。 使用var anotherIdeation = context.Ideations.SingleOrDefault(i => i.Id == 1);甚至无法运行数据库查询var anotherIdeation = context.Ideations.SingleOrDefault(i => i.Id == 1); 因为查询的默认合并选项是AppendOnly ,即仅当尚无具有该键的附加实体时才添加新实体。 因此, anotherIdeation想法仍然是非代理。

GetById方法中调用Find之前,可以使用Local检查该实体是否已附加:

bool isIdeationAttached = context.Ideations.Local.Any(i => i.Id == id);

根据@ ken2k的评论,从EF 4开始的新模型的默认设置是默认启用延迟加载。 对于EF 1,这是不允许的。 如果您将模型从1迁移到4,则默认情况下会保持关闭状态。 您需要修改上下文以将其打开。

话虽如此,您通过调试表明它是正确的。 在这种情况下,请检查您的使用方案。 是否有可能在获取子对象之前先处理了上下文。 通常,当数据绑定到LINQ查询时,当在using块中配置了上下文,并且直到通过using块的作用域之后,才发生实际的迭代,这时我们会看到这种情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM