C# 实体框架代码优先IQueryable

C# 实体框架代码优先IQueryable,c#,entity-framework-4.1,C#,Entity Framework 4.1,我首先使用实体框架代码,遇到了一个小障碍。我有一个类“人”,定义如下: 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

我首先使用实体框架代码,遇到了一个小障碍。我有一个类“人”,定义如下:

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();
IEnumerable results=person.History
.OrderBy(h=>h.OnDate)
.Take(50)
.ToArray();
它似乎为这个人提取了所有的历史,然后在记忆中排序等等。对我遗漏的东西有什么建议吗


提前谢谢

因为您查询的是EF给定的
IEnumerable
(即LINQ到对象)而不是
IQueryable
(即LINQ到实体)

相反,你应该使用

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

这个问题和公认的答案都有点过时了。像这样的代码,作为原始问题点,将从数据库中加载此人的整个历史记录-不好

var results = person
    .History
    .OrderBy(h => h.OnDate)
    .Take(50)
    .ToArray();
使用EF 6有一个简单的解决方案。无需重新排列查询,您可以通过使用、和使其以
IQueryable
的方式工作


你希望看到什么样的行为?是否未能将结果限制为50条记录?我认为预期的行为是在数据库中对其进行排序我希望它通过发送订单并限制到服务器,从而导致SQL server进行排序和限制。取而代之的是,它似乎将所有的历史记录、该联系人的所有30000+元素拉入内存,然后在内存中执行顺序和限制。为什么您确定它正在内存中加载?您看到生成的sql了吗?这是EF code first-假定已从数据库检索到
Person
,因此其导航属性
History
已连接到上下文。@BrokenGlass是,已连接。但是它的类型是
ICollection
而不是
IQueryable
。因此,当您访问
person.History
时,它将加载所有历史对象。啊,您当然是对的,因为延迟加载将启动并加载整个集合。得到我的+1那太糟糕了。我想这一切都是有道理的,我只是希望有一种方法可以这样做。有一个关于EF 5的想法。。。IQueryableCollection.:-)您总是可以编写一个[NotMapping]属性,在引擎盖下执行IQueryable操作。
var results = dbContext
    .Entry(person)
    .Collection(p => p.History)
    .Query()
    .OrderBy(h => h.OnDate)
    .Take(50)
    .ToArray();