รวมการอ้างอิงหลายรายการในระดับที่สอง


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 ฉันต้องการดึงข้อมูลทั้งหมดจากตารางระดับด้วยข้อมูลจากตารางผู้ติดต่อจากตาราง Titre จากตาราง TypeContact และอื่น ๆ ... ด้วยคำสั่งเดียว ด้วย Include / ThenInclude API ฉันสามารถเขียนสิ่งนี้:

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

แต่หลังจากคุณสมบัติ Titre ฉันไม่สามารถรวมการอ้างอิงอื่น ๆ เช่น TypeContact, Langue, Fonction ... รวมวิธีการแนะนำวัตถุระดับและ ThenInclude แนะนำวัตถุ Titre แต่ไม่ใช่วัตถุที่ติดต่อ ฉันจะรวมการอ้างอิงทั้งหมดจากรายชื่อผู้ติดต่อของฉันได้อย่างไร? เราสามารถบรรลุสิ่งนี้ด้วยคำสั่งเดียวได้หรือไม่?

คำตอบ:


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
BTW คำถามนี้เป็นแรงบันดาลใจให้ฉันสร้างปัญหา# 2124
bricelam

ทำไมไม่: มัน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

2
โซลูชันนี้ใช้งานได้ แต่คำสั่ง SQL ที่เป็นผลลัพธ์ส่งผลให้ LEFT JOIN สามรายการกับผู้ติดต่อ (อย่างน้อยก็ในประสบการณ์ของฉัน) นั่นคือไม่มีประสิทธิภาพอย่างมาก จะต้องมีวิธีที่ดีกว่านี้
EL MOJO

3
สำหรับผู้หารายใหม่: ในปี 2020 ด้วย EF Core 3.1 การทดสอบของฉันกับโซลูชันที่ได้รับการยอมรับทำงานได้ดีและไม่ส่งผลให้มีการรวมเหลือ 3 รายการ
heringer

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.