web-dev-qa-db-ja.com

エンティティフレームワーク - 複数レベルのプロパティを含める

Include()メソッドはオブジェクトのリストに対しては非常にうまく機能します。しかし、もし私が2レベルの深さに行かなければならないならば、どうですか?たとえば、以下のメソッドは、ここに示すプロパティを含むApplicationServersを返します。ただし、ApplicationsWithOverrideGroupは他の複雑なオブジェクトを保持する別のコンテナです。そのプロパティでInclude()もできますか?それともどのように私はそのプロパティを完全にロードさせることができますか?

今のところ、このメソッドは:

public IEnumerable<ApplicationServer> GetAll()
{
    return this.Database.ApplicationServers
        .Include(x => x.ApplicationsWithOverrideGroup)                
        .Include(x => x.ApplicationWithGroupToForceInstallList)
        .Include(x => x.CustomVariableGroups)                
        .ToList();
}

ApplicationプロパティまたはCustomVariableGroupプロパティ(下)ではなく、Enabledプロパティ(下)にのみ入力します。どうすればこれを実現できますか?

public class ApplicationWithOverrideVariableGroup : EntityBase
{
    public bool Enabled { get; set; }
    public Application Application { get; set; }
    public CustomVariableGroup CustomVariableGroup { get; set; }
}
311
Bob Horn

EF 6の場合

using System.Data.Entity;

query.Include(x => x.Collection.Select(y => y.Property))

その他の例については、 備考 を参照してください。

必ずラムダを取り込むIncludeのバージョンを取得するためにusing System.Data.Entity;を追加してください。


EFコアの場合

新しいメソッドを使う ThenInclude

query.Include(x => x.Collection)
     .ThenInclude(x => x.Property);
600
Diego Torres

私があなたを正しく理解しているならば、あなたは入れ子になったプロパティを含めることについて尋ねています。もしそうなら:

.Include(x => x.ApplicationsWithOverrideGroup.NestedProp)

または

.Include("ApplicationsWithOverrideGroup.NestedProp")  

または

.Include($"{nameof(ApplicationsWithOverrideGroup)}.{nameof(NestedProp)}")  
58
Judo

EF Core:「Then Include」を使用して複数のレベルをロードする:例:

var blogs = context.Blogs
    .Include(blog => blog.Posts)
        .ThenInclude(post => post.Author)
        .ThenInclude(author => author.Photo)
    .ToList();
44
thangcao

私は、Entity Framework 6(.Net Coreスタイル)をちょっとだけ手助けして、素敵な方法でサブエンティティを含めました。

それは今NuGetにあります:インストールパッケージThenInclude.EF6

using System.Data.Entity;

var thenInclude = context.One.Include(x => x.Twoes)
    .ThenInclude(x=> x.Threes)
    .ThenInclude(x=> x.Fours)
    .ThenInclude(x=> x.Fives)
    .ThenInclude(x => x.Sixes)
    .Include(x=> x.Other)
    .ToList();

このパッケージはGitHubで入手可能です。

26
Lenny32

私も複数のインクルードを使用しなければなりませんでした、そして第3レベルで私は複数の特性を必要としました

(from e in context.JobCategorySet
                      where e.Id == id &&
                            e.AgencyId == agencyId
                      select e)
                      .Include(x => x.JobCategorySkillDetails)
                      .Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.DurationType))
                      .Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.RuleType))
                      .Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.RateType))
                      .FirstOrDefaultAsync();

これは誰かに役立つかもしれません:)

16
dnxit

MSDNのより多くの EFCoreの例 は、IncludeThenIncludeを使って非常に複雑なことを実行できることを示しています。

これは、どれほど複雑になる可能性があるかを示す良い例です(これはすべて1つのステートメントです)。

viewModel.Instructors = await _context.Instructors

      .Include(i => i.OfficeAssignment)

      .Include(i => i.CourseAssignments)
        .ThenInclude(i => i.Course)
            .ThenInclude(i => i.Enrollments)
                .ThenInclude(i => i.Student)

      .Include(i => i.CourseAssignments)
        .ThenInclude(i => i.Course)
            .ThenInclude(i => i.Department)

      .AsNoTracking()
      .OrderBy(i => i.LastName)
      .ToListAsync();

Includeの後でもどうやってThenIncludeをチェーニングすることができるのかを見てください。そうすることであなたはトップレベルのエンティティ(Instructors)のレベルに戻ることができます。

同じ「第1レベル」のコレクション(CourseAssignments)を複数回繰り返し、その後に別々のThenIncludesコマンドを続けて別の子エンティティに到達することもできます。

実際のクエリはIncludeまたはThenIncludesチェーンの最後にタグ付けする必要があります。以下は機能しません。

var query = _context.Instructors.AsQueryable();
query.Include(i => i.OfficeAssignment);

var first10Instructors = query.Take(10).ToArray();

ロギングを設定し、1つか2つ以上のものを含める場合はクエリが制御不能にならないようにすることを強くお勧めします。それが実際にどのように機能するかを見ることは重要です - そして、それぞれの別々の 'include'は、大規模な結合が冗長なデータを返さないようにするための新しいクエリです。

実際にエンティティを編集して再保存することを意図していない場合は、AsNoTrackingを使用すると作業が大幅にスピードアップします。

10
Simon_Weaver

文字列リテラルを使用しても構わない場合は、対応する関係の多重度に関係なく、文字列オーバーロードを使用してネストされたレベルを含めることができることを明確に説明します。

query.Include("Collection.Property")
3
mrmashal