두 번째 수준에 대한 여러 참조 포함


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 테이블 등의 데이터를 단일 명령으로 검색하고 싶습니다. Include / ThenInclude API를 사용하면 다음과 같이 작성할 수 있습니다.

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

그러나 Titre 속성 이후에는 TypeContact, Langue, Fonction과 같은 다른 참조를 포함 할 수 없습니다. Include 메서드는 Tiers 개체를 제안하고 ThenInclude는 Titre 개체를 제안하지만 Contact 개체는 제안하지 않습니다. 내 연락처 목록에있는 모든 참조를 포함하려면 어떻게해야합니까? 하나의 명령으로 이것을 달성 할 수 있습니까?

답변:


164

.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); 작동하지 않을까요?
Doug

1
@Doug 아니요, Queryable매번 새 개체를 만들고 평가하지 않습니다. contacts당신이 할당 한 원래의 가치만을 가질 것입니다.
bricelam

2
이 솔루션은 작동하지만 결과 SQL 문은 (적어도 내 경험으로는) 연락처와 함께 세 개의 LEFT JOIN을 생성합니다. 그것은 매우 비효율적입니다. 더 나은 방법이 있어야합니다.
EL MOJO jul.

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.