在第二层包括一些参考


87

假设我们有这个模型:

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对象。如何包含联系人列表中的所有引用?我们可以用一条指令来实现吗?

Answers:


153

.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 '16

如果tiers.ContactsList<T>?那你怎么指定项目呢?
shashwat

2
此解决方案有效,但是生成的SQL语句导致三个带有联系人的LEFT JOIN(至少以我的经验)。那是非常低效的。一定有更好的方法。
EL MOJO

7

为了完整起见:

如果嵌套属性Include 不是集合属性,则也可以直接包含嵌套属性例如:

_dbSet
    .Include(tier => tier.Contact.Titre)
    .Include(tier => tier.Contact.TypeContact)
    .Include(tier => tier.Contact.Langue);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.