Sertakan beberapa referensi di tingkat kedua

93

Asumsikan kita memiliki model ini:

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

dan

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

Dengan EF7 saya ingin mengambil semua data dari tabel Tiers, dengan data dari tabel Contact, dari tabel Titre, dari tabel TypeContact dan seterusnya ... dengan satu instruksi tunggal. Dengan Include / ThenInclude API saya dapat menulis sesuatu seperti ini:

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

Tetapi setelah properti Titre, saya tidak dapat menyertakan referensi lain seperti TypeContact, Langue, Fonction ... Metode Sertakan menyarankan objek Tiers, dan ThenInclude menyarankan objek Titre, tetapi bukan objek Kontak. Bagaimana saya bisa memasukkan semua referensi dari daftar Kontak saya? Bisakah kita mencapai ini dengan satu instruksi?

Christophe Gigax
sumber

Jawaban:

163

.ThenInclude()akan berantai dari yang terakhir .ThenInclude()atau yang terakhir .Include()(mana saja yang lebih baru) untuk menarik beberapa level. Untuk menyertakan beberapa saudara di tingkat yang sama, cukup gunakan .Include()rantai lain . Memformat kode dengan benar dapat meningkatkan keterbacaan secara drastis.

_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.
bricelam.dll
sumber
3
BTW, pertanyaan ini menginspirasi saya untuk membuat edisi # 2124
bricelam
mengapa tidak: var contacts = _dbSet.Include(tiers => tiers.Contacts); contacts.ThenInclude(contact => contact.Titre); contacts.ThenInclude(contact => contact.TypeContact); contacts.ThenInclude(contact => contact.Langue); Bukankah itu berhasil?
Doug
1
@Doug Tidak, Anda akan membuat Queryableobjek baru setiap kali dan tidak pernah mengevaluasinya. contactshanya akan memiliki nilai asli yang Anda tetapkan padanya.
bricelam
2
Solusi ini berfungsi tetapi pernyataan SQL yang dihasilkan menghasilkan tiga GABUNG KIRI dengan Kontak (setidaknya dalam pengalaman saya). Itu sangat tidak efisien. Pasti ada cara yang lebih baik.
EL MOJO
3
Untuk pencari baru: pada tahun 2020, dengan EF Core 3.1, pengujian saya dengan solusi yang diterima bekerja dengan baik dan tidak menghasilkan 3 penggabungan lagi.
heringer
8

Demi kelengkapan:

Dimungkinkan juga untuk menyertakan properti bertingkat secara langsung Include jika mereka bukan properti koleksi seperti:

_dbSet
    .Include(tier => tier.Contact.Titre)
    .Include(tier => tier.Contact.TypeContact)
    .Include(tier => tier.Contact.Langue);
Risadinha
sumber