如何使用Include()只获取第一个元素

本文关键字:获取 第一个 元素 何使用 Include | 更新日期: 2023-09-27 18:25:07

我想得到所有的车,但只得到每辆车的最新报告,而不是所有的卡和它们的所有报告。一辆车可以有多个报告。

// with this i would get all cars with all reports for each car.
// How can i get all cars with only the last report for each car?
context.Cars.Include("Reports");

我试过这样的东西:

context.Cars.Include(c => c.Reports.OrderByDescending(r => r.Id).FirstOrDefault())
.Take(10)
.ToList();

但这并没有奏效。

如何使用Include()只获取第一个元素

我同意@GaryMgill的观点,Include扩展方法不允许部分加载导航属性。您可以使用显式加载:

var car=yourPreviousQuery.FirstOrDefault(); // This is just an example to have a Car instance
context.Entry(car) 
    .Collection(b => b.Reports) 
    .Query().OrderByDescending(r => r.Id).Take(1) 
    .Load(); 
.Select(p => new
{
    Car = p,
    Report = p.Reports.OrderByDescending(r => r.Id).FirstOrDefault()
})

这将提供一个匿名对象列表,您可以将其转换为IEnumerable<Cars>

假设您有类似的Dto的/View模型

public class CarDto
{
    public int Id { set; get; }
    public string Name { set; get; }
}
public class ReportDto
{
    public int Id { set; get; }
    public string Name { set; get; }
}
public class CatSimpleDto
{
    public CarDto Car { set; get; }
    public ReportDto FirstPost { set; get; }
}

您可以按Reports降序排序(on Id或Insert timestamp等)然后拿走第一个项目。

var carsWithFirstReport= db.Cars.
Select(s => new CatSimpleDto
{
    Car = new CarDto { Id = s.Id, Name = s.Name },
    FirstPost = s.Reports.OrderByDescending(f => f.Id).Take(1)
    .Select(x => new ReportDto
    {
        Id = x.Id,
        Name = x.Name
    }).FirstOrDefault()
}).ToList();

与选择实体框架创建的实体相比,投影到DTO/POCO将消除延迟执行(因此在访问导航属性时在数据库上执行更多查询)。点击此处了解更多信息。