在第二级包含多个引用

Chr*_*gax 69 entity-framework-core asp.net-core-mvc

假设我们有这个模型:

public class Tiers
{
    public List<Contact> Contacts { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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; }
}
Run Code Online (Sandbox Code Playgroud)

使用EF7,我想从Tiers表中检索所有数据,包括Contact表中的数据,Titre表中的数据,TypeContact表中的数据等等......只需一条指令.使用Include/ThenInclude API,我可以编写如下内容:

_dbSet
     .Include(tiers => tiers.Contacts)
          .ThenInclude(contact => contact.Titre)
     .ToList();
Run Code Online (Sandbox Code Playgroud)

但是在Titre属性之后,我不能包含其他引用,如TypeContact,Langue,Fonction ...... Include方法建议Tiers对象,ThenInclude建议Titre对象,但不是Contact对象.如何在联系人列表中包含所有引用?我们能用一条指令实现这一目标吗?

bri*_*lam 115

.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.
Run Code Online (Sandbox Code Playgroud)

  • 对于新搜索者:2020 年,使用 EF Core 3.1,我对已接受的解决方案进行的测试运行良好,并且没有导致 3 个左连接。 (12认同)
  • 好的谢谢!我以为会有更好的解决方案;) (3认同)
  • 此解决方案有效,但生成的 SQL 语句会导致三个 LEFT JOIN 与联系人(至少以我的经验)。这是非常低效的。一定有更好的方法。 (3认同)
  • 顺便说一句,这个问题激发了我创造问题[#2124](https://github.com/aspnet/EntityFramework/issues/2124) (2认同)
  • @Doug 不,您每次都会创建新的`Queryable` 对象并且永远不会评估它们。`contacts` 只会拥有您分配给它的原始值。 (2认同)

Ris*_*nha 12

为了完整起见:

也可以直接包含嵌套属性Include ,以防它们不是像这样的集合属性

_dbSet
    .Include(tier => tier.Contact.Titre)
    .Include(tier => tier.Contact.TypeContact)
    .Include(tier => tier.Contact.Langue);
Run Code Online (Sandbox Code Playgroud)