我有以下两个实体:
public class Person
{
public Person()
{
Items = new HashSet<Item>();
}
public string Id { get; set; }
public string Name { get; set; }
public ICollection<Item> Items { get; private set; }
}
public class Item
{
public string Id { get; set; }
public DateTime Date { get; set; }
public string Status { get; set; }
public Person Person { get; set; }
public string PersonId { get; set; }
}
我想选择所有的人,并且只包括他们最近的项目(按日期排序)。
我想这样的办法应该管用:
var persons = _context.Persons
.Include(e => e.Items.OrderByDescending(i => i.Date).Take(1))
.ToList();
但显然EF Core无法做到这一点。 items集合将变得非常大(>20000),因此不希望为每个人加载它们。 我该怎么做呢?
是的,不幸的是,您不能以这种方式使用include
扩展方法,但是如果您愿意使用第三方库,那么我建议您使用Entity Framework Plus,使用该库您可以做到:
var persons = _context.Persons
.IncludeFilter(e => e.Items.OrderByDescending(i => i.Date).Take(1))
.ToList();
有第二个选项解释在链接中我张贴使用全局过滤器,但我认为这个解决方案是接近什么你正在寻找。
第三种选择是用您期望的结果投射查询:
var persons = _context.Persons
.Select(e=> new {Person=e,
Item=e.Items.OrderByDescending(i => i.Date)
.Take(1)
})
.ToList();
是的,不幸的是误用了include
。
但是,对于查询,可以在items
上使用groupby
和子查询。
查询按PersonId分组,按组内日期排序的项目,并首先获取这些项目。
希望您将有一些相关的索引来加快db端的查询速度。
应该是这样的:
_context.Items.GroupBy(i => i.PersonId)
.Select(g => g.OrderByDescending(p => p.Date).FirstOrDefault())