在第二级别中包含几个参考文献

160

假设我们有这个模型:

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对象。我该如何在我的联系人列表中包括所有这些引用?我们能否用一条指令完成这个操作?

2个回答

296

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

7
顺便说一下,这个问题启发我创建了一个问题编号为[#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
3
不,你每次都会创建新的“Queryable”对象,而且永远不会对其进行评估。 "contacts" 只会保留你分配给它的初始值。 - bricelam
4
这个解决方案可行,但是生成的SQL语句会产生至少三个与Contacts表进行的LEFT JOIN操作(至少在我的经验中是这样)。这种效率极低。肯定有更好的方法。 - EL MOJO
22
针对新的使用者:在2020年,使用EF Core 3.1时,我的测试结果显示已接受的解决方案可行,并且不会导致3个左连接。 - heringer
显示剩余4条评论

29

为了完整起见:

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接