(代理)为什么在实体框架中使用懒惰加载的层次结构会产生不同的行为

本文关键字:层次结构 加载 为什么 代理 实体 框架 | 更新日期: 2023-09-27 17:53:08

需要澄清为什么实体框架在以下场景A和b中的行为不同

在这些场景中,上下文仍然存在,我们使用延迟加载和以下实体:

public class Root
{
    //... some Properties
    public virtual ICollection<Child> GoingDown { get; set; }
}
public class Child
{
    //... some Properties
    public virtual Root Root { get; set; }
    public virtual ICollection<DeeperChild> GoingDeeper { get; set; }
}
public class DeeperChild
{
    public virtual Child Child { get; set; }
    public virtual ICollection<MoreDeeperTypeWithVirtualStuff> GoingFurtherDown { get; set; }
}

场景

Root root = Context.Roots.First();
Console.WriteLine(root.GoingDown.FirstOrDefault().GetType().ToString());
//Display System.Data.Entity.DynamicProxies.Child_[SomeGuid]

情形B

Root root = Context.Roots.First(r => r.Id == SomeId);
Console.WriteLine(root.GoingDown.FirstOrDefault().GetType().ToString());
//Display MyNamespace.Child

因为返回类型不是"代理"第一,延迟加载在场景b中不再工作了。它不应该像场景A那样返回代理类型吗?

<标题>编辑:

问题与上面的场景无关
经过进一步的研究,似乎不同的行为与场景无关,而是与获取的根有关。在每种情况下,加载的根都是代理类型。当深入到子节点时,除了场景b的特定根实例之外,子节点的类型总是代理。在代码的这一点上,该根可能在EntityFramework的缓存中,因为该根在该点之前被查询了两次(在另外两个类中)。这两个调用不获取子节点

我做了新的测试
在根实例的第一次获取中,我添加了子节点的虚拟使用,并且子节点的类型是proxy。然而,即使在第一次调用时使用虚拟,当达到第二次和第三次取回时,child的类型也不再是代理了。

(代理)为什么在实体框架中使用懒惰加载的层次结构会产生不同的行为

我发现了发生了什么,在第一次和第二次获取根之间执行了一些代码,刷新了所有子节点,rec创建了它们的全新实例。因此,子进程不再来自数据库,从而使它们不再是"代理"类型,从而使惰性加载不可用。