2016-12-15 13 views
1

我認識到,當我使用.NET Core Web API中的實體框架核心查詢包含相關數據的對象列表時,只要我不嘗試使用匿名類隱藏一些領域。EntityFramework使用匿名類的核心加載相關數據導致多個子查詢

當我使用匿名類時,會從數據庫中加載相關數據,併爲每個條目調用一次。在下面的例子中,這意味着每個人都會創建一個數據庫調用來查詢相關詳細信息(根據日誌文件)。

由於人員列表很長,這意味着數據庫受到了我試圖避免的查詢的打擊。

簡單的情況有兩個表:

Person (id, firstname, lastname, someOtherField) 

PersonDetails (id, PersonId, DetailText, someOtherDetailField) 

,如果我挑的所有領域,並使用預先加載可與一個DB調用完美的罰款。

鑑於此代碼:


public IActionResult Get() 
{ 
    var result = _db.Media.Include(m => m.Thumbnail); 
    return Ok(result); 
} 

結果輸出這樣的:


[ 
    { 
    "id": 1, 
    "firstname": "First1", 
    "lastname": "Last1", 
    "groupAssignment": [], 
    "personDetails": [ 
     { 
     "id": 1, 
     "personId": 1, 
     "detailText": "details1" 
     } 
    ] 
    } 
] 

我找了只選擇對人的字段和PersonDetails只選定字段,這樣的輸出:


[ 
    { 
    "firstname": "First1", 
    "lastname": "Last1", 
    "personDetails": [ 
     { 
     "detailText": "details1" 
     } 
    ] 
    } 
] 

目前我在這個狀態下使用一個匿名類隱藏person fi視場:


public IActionResult Get() 
{ 
    var result = _dbContext.Person 
        .Include(p => p.PersonDetails) 
        .Select(
         p => new 
         { 
          p.Firstname, 
          p.Lastname, 
          p.PersonDetails 
         } 
        ); 
    return Ok(result); 
} 

但是,這給我留下了兩個問題:

  1. 我導致單獨的數據庫查詢每個人請求PersonDetails
  2. 出於某種原因,我不能用
    p.PersonDetails.Select(d => new {d.DetailText})
    過濾PersonDetails的字段。

任何建議如何查詢/返回所需的輸出?

回答

0

從其他的問題,我想通了,出現了兩個問題

.AsEnumerable()使得EF與一個呼叫查詢相關數據(什麼並不意味着整個查詢是一個呼叫,但至少相關的所有問題的答案數據通過一次調用查詢)

personDetails =使匿名數據成爲一個名爲var的允許僅選擇特定字段的名稱。


public IActionResult Get() 
{ 
    var result = _dbContext.Person 
     .Include(p => p.PersonDetails) 
     .AsEnumerable() 
     .Select(
      p => new 
      { 
       p.Firstname, 
       p.Lastname, 
       personDetails = p.PersonDetails.Select(d => new {d.DetailsText}) 
      } 
     ); 
    return Ok(result); 
}