【问题标题】:EF classes containing collections: Lists induce to use memory when navigating包含集合的 EF 类:列表在导航时会导致使用内存
【发布时间】:2013-12-02 15:28:41
【问题描述】:

当想要使用 EF 导航(通过类的属性导航)时,List<T>´s 都在内存中处理。

例如我有这个 EF 模型类:

class School
{
    public virtual ICollection<Groups> Groups { get; set; }
    ...

    public School()
    {
         this.Courses = new List<Group>();  // List<T>!!
    }
}

如果我这样做:

someSchool.Groups.Count

我将计算内存中的组而不是 SQL(即:这些不会像 "select count(*) from Groups join School Where SchoolId = ..." 那样计算)

所以我的问题是.. 我应该使用什么来代替 List?
IEnumerable 是一个接口,所以我不能有一个新的 IEnumerable,... IQueryable 也是..

如果没有适合于此的集合类,那么我想我应该使用我的 DbContext 实例。像这样:

(new MyDbContext()).Groups.Count(g => g.SchoolId == ...)

如果是这样,那么:为什么会有EF导航?!??




编辑: 好吧,也许我应该使用真实信息:

  1. 我已经在使用 ICollection(我在帖子中使用了 IEnumerable,因为我认为它们相似)

  2. 这是慢查询:domain.Persons.Count(p =&gt; p.IsStudent &amp;&amp; p.GuardianId != null &amp;&amp; p.Guardian.Mobile.Equals(""))

  3. 这是快速查询:db.Persons.Count(p =&gt; p.Domains.Any(d =&gt; d.DomainId == domain.DomainId) &amp;&amp; p.IsStudent &amp;&amp; p.GuardianId != null &amp;&amp; p.Guardian.Mobile.Equals(""))

如您所见,2 和 3 非常相似……一个使用导航,另一个不使用。

【问题讨论】:

    标签: entity-framework


    【解决方案1】:

    您应该改用ICollection&lt;T&gt; 并将您的属性定义为虚拟,以便您可以延迟加载并获取您的 Count()。

    // Example
    public virtual ICollection<Apple> Apples{get;set;}
    

    virtual 关键字使 EF 能够在您访问 getter 时为您覆盖其行为和延迟加载实体。

    【讨论】:

    • 对不起,我在主帖中输入了 IEnumerable 但我已经尝试过 ICollection 并且它在内存中完成了它。也许我的错在别处如果你说的是真的
    • 您是否也将其定义为“虚拟”?
    • 可能你的实体配置不正确。确保您正确映射了导航属性并在您的上下文中启用了延迟加载。
    • “在你的上下文中启用延迟加载”,不是默认吗?
    • 是的,如果您没有明确禁用它是默认设置。
    猜你喜欢
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 2018-06-09
    • 2021-09-07
    • 1970-01-01
    • 2021-05-26
    相关资源
    最近更新 更多