【问题标题】:Entity Framework Code First IQueryable实体框架代码优先 IQueryable
【发布时间】:2011-06-24 15:42:34
【问题描述】:

我首先使用实体​​框架代码并遇到了一个小障碍。我有一个这样定义的“人”类:

public class Person
{
    public Guid Id { get; set; }
    public virtual ICollection<History> History { get; set; }
}

以及这样定义的“历史”类:

public class History
{
    public Guid Id { get; set; }
    public virtual Person Owner { get; set; }
    public DateTime OnDate { get; set; }
}

但是,当我打电话时:

IEnumerable<History> results = person.History
                               .OrderBy(h => h.OnDate)
                               .Take(50)
                               .ToArray();

它似乎为该人提取了所有历史记录,然后在内存中对其进行排序等。关于我缺少什么的任何建议?

提前致谢!

【问题讨论】:

  • 您希望看到什么行为?是否未能将结果限制为 50 条记录?
  • 我认为预期的行为是在数据库中订购它
  • 我期待它通过服务器发送订单和限制,导致 SQL 服务器进行排序和限制。相反,它似乎将所有历史记录拉入内存,该联系人的所有 30,000 多个元素,然后在内存中执行顺序和限制。
  • 为什么你确定它正在将它加载到内存中?看到生成的sql了吗?

标签: c# entity-framework-4.1


【解决方案1】:

因为您查询的是 IEnumerable(即:LINQ to Objects)而不是 EF 给出的 IQueryable(即:LINQ to Entities)。

你应该使用

IEnumerable<History> results = context.History.Where(h => h.Person.Id = "sfssd").OrderBy(h => h.OnDate).Take(50)

【讨论】:

  • 这是 EF 代码优先 - 假设 Person 是从数据库中检索到的,因此其导航属性 History 连接到上下文。
  • @BrokenGlass 是的,它已连接。但它的类型为ICollection&lt;History&gt; 而不是IQueryable&lt;History&gt;。因此,当您访问person.History 时,它将加载所有历史对象。
  • 啊,你当然是对的,因为延迟加载会启动并加载完整的集合。得到了我的 +1
  • 那太糟糕了。我想这一切都是有道理的,我只是希望有办法做到这一点。 EF 5 有一个想法... IQueryableCollection。 :-)
  • 您总是可以编写一个 [NotMapped] 属性来完成 IQueryable 的工作。
【解决方案2】:

这个问题和接受的答案都有点老了。作为原始问题点,这样的代码会从数据库中加载该人的整个历史记录 - 不好!

var results = person
    .History
    .OrderBy(h => h.OnDate)
    .Take(50)
    .ToArray();

使用 EF 6 有一个简单的解决方案。在不重新排列查询的情况下,您可以通过使用DbContext.Entry methodDbEntryEntity.Collection methodDbCollectionEntry.Query method 使其以IQueryable 的方式工作。

var results = dbContext
    .Entry(person)
    .Collection(p => p.History)
    .Query()
    .OrderBy(h => h.OnDate)
    .Take(50)
    .ToArray();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-01
    • 2014-05-23
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    • 2012-05-31
    • 2012-12-30
    相关资源
    最近更新 更多