2016-02-15 60 views
1

我正在使用EF 7和MVC 5創建Web應用程序。我需要從我的數據庫中選擇所有標題行。如何從包含中選擇最後一行

這些行會用一個類象下面這樣:

public class Log_Header 
{ 
    [Key] 
    public int Id { get; set; } 
    public string App_Name { get; set; } 
    public string App_Url { get; set; } 
    public string Submitted_By { get; set; } 
    public string App_Contact { get; set; } 
    public string App_Description { get; set; } 

    public ICollection<Log_Detail> Details { get; set; } 
} 

正如你可以看到我有Log_Details的集合。

我使用的語句如下:

public IEnumerable<Log_Header> getLogHeaders() 
{ 
    return _context.LogHeader.Include(t => t.Details).ToList(); 
} 

現在到了我有這個問題,我只能從Details需要最後一排(最大ID行),但我無法找到一個方法來做到這一點。我已經試過,沒有運氣的一些方法,認爲這將類似於此:

_context.LogHeader.Include(t => t.Details.Last()).ToList(); 

我不斷收到的錯誤是:

的「」類型的異常出現在 EntityFramework.Core.dll但在用戶代碼中沒有處理

其他信息:無法轉換類型 「Remotion.Linq.Clauses.Expressions.SubQueryExpression」的目的是鍵入 「System.Linq.Expressions.MemberExpression」。

如果任何人有任何線索,請發表評論或回答,請記住這是使用EF 7

+0

Include正在等待導航屬性的路徑,而不是實際的成員。我相信你最好的選擇是懶加載必要的對象,而不是急切地加載樹。 – DevilSuichiro

+0

@DevilSuichiro謝謝你的回覆。我相信EF 7目前不支持延遲加載......所以這是一個問題。 – furkick

+0

是否嘗試_context.LogHeader.Include(t => t.Details.LastOrDefault())。ToList(); –

回答

1

EF不支持計有隻首/末/不管行。 EF僅支持包括整個表格(即,它執行JOIN)。 因此,您將始終獲得Log_Header.Count() * Log_Detail().Count()行。 這將花費你大量的表現。

更好地加載數據到數據庫的2次往返。 更好:並行和異步執行它們。

public async Task<IEnumerable<Log_Header>> GetHeaderWithLastDetailAsync() 
{ 
    var headerTask = GetLogHeadersAsync(); 
    var detailTask = GetLastDetailByHeaderIdAsync(); 

    await Task.WhenAll(headerTask, detailTask).ConfigureAwait(false); 

    var header = headerTask.Result; 
    var detail = detailTask.Result; 

    foreach(var h in header) 
    { 
     Log_Detail d; 
     if(detail.TryGetValue(h.Id, out d) 
      h.Details.Add(d); 
    } 
} 

public async Task<IEnumerable<Log_Header>> GetLogHeadersAsync() 
{ 
    using(var context = new MyContext()) 
    { 
     context.Configuration.AutoDetectChangesEnabled = false; 
     context.Configuration.ProxyCreationEnabled = false; 
     return await context.LogHeader.ToListAsync().ConfigureAwait(false); 
    } 
} 

public async Task<IDictionary<int, Log_Detail>> GetLastDetailByHeaderIdAsync() 
{ 
    using(var context = new MyContext()) 
    { 
     context.Configuration.AutoDetectChangesEnabled = false; 
     context.Configuration.ProxyCreationEnabled = false; 
     return await context.LogDetail.ToDictionaryAsync(d => d.HeaderId).ConfigureAwait(false); 
    } 
}