代码首先加载嵌套,没有递归

本文关键字:递归 嵌套 加载 代码 | 更新日期: 2023-09-27 18:14:33

我有一个可以包含许多节的工作表。每个节也可以包含许多节。我想加载表,它的部分,以及所有的小节与尽可能少的往返数据库。实际上,我认为这通常需要1-2个关卡,但也有可能达到16个关卡。下面是代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
public class Sheet {
    public long Id { get; set; }
    // more fields
    public virtual IList<Section> Sections { get; set; }
}
public class Section {
    public long Id { get; set; }
    public long SheetId { get; set; }
    [ForeignKey("SheetId")]
    public virtual Sheet Sheet { get; set; }
    public long? ParentId { get; set; }
    [ForeignKey("ParentId")]
    public virtual Section Parent { get; set; }
    public virtual IList<Section> Sections { get; set; }
    // more fields
}
public class MyDbContext : DbContext {
    public DbSet<Sheet> Sheets { get; set; }
    public DbSet<Section> Sections { get; set; }
    public Sheet GetSheetConfiguration(long id) {
        Configuration.LazyLoadingEnabled = false;
        Sheet rtn;
        rtn = Sheets.Find(id);
        (Sections.Where(sect => sect.SheetId == id)).ToList();
        return rtn;
    }
}

创建所需的表结构:表格:Id (pk),…章节:Id (pk), SheetId(非null), ParentId (null)

GetSheetConfiguration方法加载与该工作表相关的所有section,并让EF对其进行排序。它得到了正确的关系,除了所有的section也在Sheet.Sections中。(我想为每个Section设置SheetId,以避免递归查询。)我如何告诉EF只使用部分,其中ParentId = null在工作表级别?-列表项

代码首先加载嵌套,没有递归

您不能避免Sheet.Sections集合被所有部分填充,因为这就是您的Sheet.SectionsSection.Sheet之间的关系所描述的:它应该具有所有部分,而不仅仅是ParentId == null的"根部分"。实体框架根据关系修复填充此集合,您不能禁用或配置此行为。

解决这个问题的一个选项是引入一个额外的集合属性,它从Sheet.Sections导航属性中读取过滤后的数据,并且不映射到数据库,以便检索根节列表,如下所示:

public class Sheet {
    public long Id { get; set; }
    // more fields
    public virtual IList<Section> Sections { get; set; }
    public IEnumerable<Section> RootSections
    {
        get { return Sections.Where(sect => sect.ParentId == null); }
    }
}

小边注:而不是…

(Sections.Where(sect => sect.SheetId == id)).ToList();

…你可以使用:

Sections.Where(sect => sect.SheetId == id).Load();

Load是一个void方法,它只将请求的实体加载到上下文中。它节省了创建不必要的List集合的开销。