实体框架代码优先IQueryable

本文关键字:IQueryable 代码 框架 实体 | 更新日期: 2023-09-27 18:00:31

我使用的是实体框架代码优先,遇到了一个小路障。我有一个类"人"定义如下:

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();

它似乎为这个人提取了所有的历史,然后在记忆中排序。关于我缺少的东西有什么建议吗?

提前感谢!

实体框架代码优先IQueryable

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

相反,你应该使用

IEnumerable<History> 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有一个简单的解决方案。在不重新排列查询的情况下,您可以使用DbContext.Entry方法、DbEntryEntity.Collection方法和DbCollectionEntry.Query方法使其以IQueryable的方式工作。

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