第2レベルにいくつかの参照を含める


93

このモデルがあると仮定します:

public class Tiers
{
    public List<Contact> Contacts { get; set; }
}

そして

public class Contact
{
    public int Id { get; set; }
    public Tiers Tiers { get; set; }
    public Titre Titre { get; set; }
    public TypeContact TypeContact { get; set; }
    public Langue Langue { get; set; }
    public Fonction Fonction { get; set; }
    public Service Service { get; set; }
    public StatutMail StatutMail { get; set; }
}

EF7では、Tiersテーブル、Contactテーブル、Titreテーブル、TypeContactテーブルなどからすべてのデータを1つの命令で取得したいと思います。Include / ThenInclude APIを使用すると、次のように記述できます。

_dbSet
     .Include(tiers => tiers.Contacts)
          .ThenInclude(contact => contact.Titre)
     .ToList();

ただし、Titreプロパティの後に、TypeContact、Langue、Fonctionなどの他の参照を含めることはできません。IncludeメソッドはTiersオブジェクトを提案し、ThenIncludeはTitreオブジェクトを提案しますが、Contactオブジェクトは提案しません。連絡先リストからすべての参照を含めるにはどうすればよいですか?1つの命令でこれを達成できますか?

回答:


163

.ThenInclude()最後.ThenInclude()または最後.Include()(どちらか新しい方)のいずれかからチェーンオフして、複数のレベルをプルします。同じレベルに複数の兄弟を含めるには、別の.Include()チェーンを使用するだけです。コードを正しくフォーマットすると、読みやすさが大幅に向上します。

_dbSet
    .Include(tiers => tiers.Contacts).ThenInclude(contact => contact.Titre)
    .Include(tiers => tiers.Contacts).ThenInclude(contact => contact.TypeContact)
    .Include(tiers => tiers.Contacts).ThenInclude(contact => contact.Langue);
    // etc.

3
ところで、この質問は私に問題#2124
bricelam 2015年

なぜそうではないのですvar contacts = _dbSet.Include(tiers => tiers.Contacts); contacts.ThenInclude(contact => contact.Titre); contacts.ThenInclude(contact => contact.TypeContact); contacts.ThenInclude(contact => contact.Langue); か:それはうまくいきませんか?
ダグ

1
@Dougいいえ、Queryable毎回新しいオブジェクトを作成し、それらを評価することはありません。contacts割り当てた元の値しかありません。
bricelam 2016年

2
このソリューションは機能しますが、結果のSQLステートメントは連絡先との3つのLEFT JOINになります(少なくとも私の経験では)。それはひどく非効率的です。より良い方法が必要です。
EL MOJO 2017

3
新規シーカーの場合:2020年にEF Core 3.1を使用した場合、受け入れられたソリューションを使用したテストは正常に機能し、3回の左結合は発生しませんでした。
ヘリンジャー

8

完全を期すために:

次のようなInclude コレクションプロパティでない場合は、を介してネストされたプロパティを直接含めることもできます

_dbSet
    .Include(tier => tier.Contact.Titre)
    .Include(tier => tier.Contact.TypeContact)
    .Include(tier => tier.Contact.Langue);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.