【问题标题】:Entity Framework loads excessive data实体框架加载过多数据
【发布时间】:2013-08-07 06:46:00
【问题描述】:

在之前使用旧版本实体框架的工作中,我习惯于使用 Eager Loading - 因此您可以获取根实体,然后根据使用“包含”的要求收集相关实体。

在我当前的项目中,我们使用数据库优先在新数据库上实现了最新版本的 EF。以这门课为例:

public partial class Zone
{
    public Zone()
    {
        this.OverrideCharges = new HashSet<OverrideCharge>();
    }

    public System.Guid RowId { get; set; }
    public string Name { get; set; }

    public virtual ICollection<OverrideCharge> OverrideCharges { get; set; }
}

OverrideCharges 对象下面还有许多子属性,以及这些子属性下的相关实体。

我们有两个上下文,实际的 DB 上下文和一组 DTO 上下文。后者的对象主要是前者的副本 - Zone_dto 对象几乎是原始对象的克隆。在这两种情况下,我都使用以下方法关闭了延迟加载:

    public CContext(): base("BreezeMetaData")
    {
        this.Configuration.LazyLoadingEnabled = false;
    }

    public UDBEntities()
        : base("name=UDBEntities")
    {
        this.Configuration.LazyLoadingEnabled = false;
    }

现在,我通过以下方式查询我的 Zone 对象:

    public List<Zone_dto> GetZones()
    {
        List<Zone> zones = _cilContext.Zones.ToList();
        List<Zone_dto> zone_dtos = new List<Zone_dto>();

        foreach (Zone zn in zones)
        {
            zone_dtos.Add(Mapper.Map<Zone, Zone_dto>(zn));
        }

        return zone_dtos;
    }

所以 - 不包括在内。并且延迟加载被禁用。我希望得到一个 Zone 对象及其直接属性的列表,但不是任何相关实体。

但我得到的是 Zone 对象,加上它们所有的 OverrideCharges,加上所有与这些 OverrideCharges 相关的实体等等,一直沿树向下。

这些数据对象并不庞大,也不是什么大问题。但是我很沮丧,因为我不明白为什么要取回我没有要求的所有数据。谁能解释一下?

【问题讨论】:

  • 您是在上下文的整个生命周期内关闭 LazyLoading,还是仅仅为了这个操作?您的上下文可能在此操作之前加载了数据,通过生成该列表,您将看到所有内容(因为加载是在您关闭延迟加载之前完成的)。
  • 它在构造函数中被禁用 - 查看编辑

标签: entity-framework


【解决方案1】:

你所描述的正是我所期望的 - 你似乎有延迟加载和急切加载。

延迟加载意味着上下文不会加载所有内容 - 它是延迟的,因为它所做的工作较少,并且只加载您具体要求的内容。 .Include() 需要 延迟加载,因为你告诉它 不要 对你 Include()ing 的事情感到懒惰。

急切加载意味着上下文将在您请求之前加载您可能需要的所有内容,方法是点击您请求的项目中的链接并加载它们导致的任何内容。关闭延迟加载后,无需告知Include() 事物,因为它会默认加载所有内容。使用.Include() 被称为急切加载,因为您告诉它对该属性使用急切加载行为;默认情况下急切加载所有内容,您不需要.Include()

设置LazyLoadingEnabled = true; 看看会发生什么。

【讨论】:

  • 这似乎完全没有区别 - 返回完全相同的数据。这表明问题出在代码中的其他地方。不知道在哪里。
  • 即使你将相关属性设置为virtual?
  • 啊哈。如果我将 then 设置为 not 虚拟,它只会加载基本属性。好的,谢谢 - 您可以调整 EF 以创建具有非虚拟导航属性的模型吗?
  • 您可以使用动态代理 - 基本上,EF 创建一个包装您的类并添加更改跟踪和延迟加载行为的类;我相当确定它适用于非虚拟导航属性,但您必须对其进行测试才能确定。尝试在关于延迟加载的行之后添加this.Configuration.ProxyCreationEnabled = true;。详情请查看this MSDN page
【解决方案2】:

可能是因为 virtual 关键字。虚拟 ICollection 将被延迟加载。

请参阅此 SO link

【讨论】:

  • 谢谢,但已经尝试过了。仍然加载完整的树。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多