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

时间:2015-11-30 15:01:32

标签: c# asp.net-mvc entity-framework

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

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

但这没有用。

3 个答案:

答案 0 :(得分:4)

我同意@GaryMcGill,Include扩展方法不允许您部分加载导航属性。你可以做的是改用Explicit Loading

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

答案 1 :(得分:3)

.Select(p => new
{
    Car = p,
    Report = p.Reports.OrderByDescending(r => r.Id).FirstOrDefault()
})

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

答案 2 :(得分:0)

假设你有像这样的Dto / Viewmodels

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&#39; / POCO将消除延迟执行(因此在访问导航属性时对数据库执行更多查询)。阅读更多相关信息here