【问题标题】:Include several references on the second level在第二级包括几个参考
【发布时间】:2015-07-16 07:57:24
【问题描述】:

假设我们有这个模型:

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

【问题讨论】:

    标签: asp.net-core-mvc entity-framework-core


    【解决方案1】:

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

    【讨论】:

    • 顺便说一句,这个问题启发了我创建问题#2124
    • 为什么不:var contacts = _dbSet.Include(tiers =&gt; tiers.Contacts); contacts.ThenInclude(contact =&gt; contact.Titre); contacts.ThenInclude(contact =&gt; contact.TypeContact); contacts.ThenInclude(contact =&gt; contact.Langue); 那不行吗?
    • @Doug 不,您每次都会创建新的Queryable 对象,并且从不评估它们。 contacts 只会拥有您分配给它的原始值。
    • 此解决方案有效,但生成的 SQL 语句会导致三个 LEFT JOIN 与联系人(至少根据我的经验)。这是非常低效的。必须有更好的方法。
    • 对于新的寻求者:在 2020 年,使用 EF Core 3.1,我使用已接受的解决方案进行的测试运行良好,并且没有导致 3 个左连接。
    【解决方案2】:

    为了完整起见:

    也可以通过Include 直接包含嵌套属性如果它们不是集合属性,如下所示:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-14
      • 1970-01-01
      • 1970-01-01
      • 2018-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多