2015-11-30 27 views
1

我想得到所有的車輛,但只有每輛車的最新報告,而不是所有的卡片和所有報告。一輛車可以有多個報告。如何只用Include()獲取第一個元素?

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

但這並沒有工作。

+2

我認爲編寫'Include()'函數的人不太可能認爲這個優化值得實施。使用兩個查詢。 –

+0

使用'.Select(...)'而不是 –

+0

@GeneR會要求太多的例子嗎?即使是更抽象的人也會這樣做。 –

回答

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

這會給匿名對象,你可以轉換到IEnumerable<Cars>

+1

雖然這個答案和@ octavioccl都達到了相同的結果,但是@ octavioccl的效果更好,因爲它清楚瞭解發生了什麼。在這裏,包含隱式地發生以滿足「選擇」,但很容易忘記或忽略認識到這一點。此外,使用顯式加載過濾器可以讓您保留實體類型,而不必投射一組匿名對象。 –

3

我與@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(); 
0

假設你有一個像這樣

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; } 
} 

DTO的/的ViewModels您可以通過在Reports降序做訂單(的ID或插入時間戳等) 並採取第一項。

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的將消除延遲執行。閱讀更多關於它here

相關問題