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; }
}
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);
私があなたを正しく理解しているならば、あなたは入れ子になったプロパティを含めることについて尋ねています。もしそうなら:
.Include(x => x.ApplicationsWithOverrideGroup.NestedProp)
または
.Include("ApplicationsWithOverrideGroup.NestedProp")
または
.Include($"{nameof(ApplicationsWithOverrideGroup)}.{nameof(NestedProp)}")
EF Core:「Then Include」を使用して複数のレベルをロードする:例:
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ThenInclude(author => author.Photo)
.ToList();
私は、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で入手可能です。
私も複数のインクルードを使用しなければなりませんでした、そして第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();
これは誰かに役立つかもしれません:)
MSDNのより多くの EFCoreの例 は、Include
とThenInclude
を使って非常に複雑なことを実行できることを示しています。
これは、どれほど複雑になる可能性があるかを示す良い例です(これはすべて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
を使用すると作業が大幅にスピードアップします。
文字列リテラルを使用しても構わない場合は、対応する関係の多重度に関係なく、文字列オーバーロードを使用してネストされたレベルを含めることができることを明確に説明します。
query.Include("Collection.Property")