2016-12-15 2 views
1

.NET Core Web APIでEntity Framework Coreを使用して関連データを持つオブジェクトのリストをクエリすると、使用しない限り正常に動作することが認識されましたいくつかのフィールドを隠す匿名クラス。EntityFramework匿名クラスのコアロード関連データ

匿名クラスを使用すると、関連するデータが各エントリの1回の呼び出しでDBから読み込まれます。下の例では、これは、(ログファイルに基づいて)関連する詳細を照会するためにDBコールが作成されることを意味します。

人のリストが長いので、これは、DBが私が避けようとしているクエリで叩かれていることを意味します。二つのテーブルと

シンプルな状況:

Person (id, firstname, lastname, someOtherField) 

PersonDetails (id, PersonId, DetailText, someOtherDetailField) 

私はすべてのフィールドを選択し、積極的なロードを使用する場合は1 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にのみ選択されたフィールドは、そのようなたを探しています出力:

現在のところ、私はこの状態で、人間fiを隠すための無神経なクラスを使用していますELDの:


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

しかし、これは二つの問題を私に残します:私はフィルタリングする

p.PersonDetails.Select(d => new {d.DetailText})
を使用することはできませんいくつかの理由についてPersonDetails
  • を要求するために、それぞれの人のために別々のデータベースクエリを起こし

    1. PersonDetailsのフィールド。

    希望の出力をどのようにクエリ/返すことができますか?私は2つの問題

    .AsEnumerable()があった考え出した他の質問の答えから

  • 答えて

    0

    はEFが1回のコールと関連データを照会することができます(全体のクエリが1つのコールが、少なくともすべての関連で何を意味するものではありません

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