【问题标题】:loading a full hierarchy from a self referencing table with EntityFramework.Core使用 EntityFramework.Core 从自引用表加载完整的层次结构
【发布时间】:2017-01-24 12:10:30
【问题描述】:

解释为什么这个问题不同于:EF - multiple includes to eager load hierarchical data. Bad practice?

  1. 如果这是一个不好的做法,可能的重复是一个基于意见的问题,而我的问题往往是关于如何做到这一点的技术解决方案,独立于意见是否是一个好的做法。我将这个决定留给产品负责人、需求工程师、项目经理和想要该功能的客户。
  2. 给出的答案要么解释了为什么这是一种不好的做法,要么使用了对我不起作用的方法(使用 Include() 和 ThenInclude() 会产生硬编码的深度,而我需要灵活的深度)。

在当前项目(.NET 核心 web api)中,我尝试从自引用表加载层次结构。

在谷歌上搜索了很多之后,我很惊讶这样的任务(我认为这是微不足道的)似乎并不微不足道。

嗯,我有这张表来形成我的层次结构:


CREATE TABLE [dbo].[Hierarchy] (
    [Id]        INT           IDENTITY (1, 1) NOT NULL,
    [Parent_Id] INT           NULL,
    [Name]      NVARCHAR (50) NOT NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_Hierarchy_Hierarchy] FOREIGN KEY ([Parent_Id]) REFERENCES [dbo].[Hierarchy] ([Id])
);

在 web api 中,我尝试返回完整的层次结构。一件可能特别的事情(可能会有所帮助)是我想加载完整的表格。

我也知道我可以使用预加载和导航属性(对于孩子来说,Parent 和 InverseParent)


_dbContext.Hierarchy.Include(h => h.InverseParent).ThenInclude(h => h.InverseParent)...

这样做的问题是,这将加载硬编码深度(例如,如果我使用 1 个 Include() 和 5 个 ThenInclude(),则为六个级别),但我的层次结构具有灵活的深度。

谁能帮助我,给我一些如何加载完整表的代码(例如,在具有 1 个 DB 调用的最佳场景中加载到内存中),然后让该方法返回完整的层次结构?

【问题讨论】:

  • 你自己尝试过什么?什么语言的代码(没有语言标签)?
  • @Sefe Entity Framework Core 显然是 C#(我认为写“a .NET core web api”会很清楚。到目前为止我已经尝试过的东西也被插入为代码 sn- p.
  • 人们正在按标签过滤他们的问题。您需要为您的问题添加正确的标签。
  • @Sefe 感谢您的建议。我添加了更多标签。我的最后一个问题得到了回答,尽管它们只被标记了两个标签。有什么建议可以解决我的问题吗?
  • 可能会有所帮助patrickdesjardins.com/blog/…

标签: c# linq asp.net-core entity-framework-core


【解决方案1】:

事实上,由于所谓的 EF(核心)关系修复,加载整个层次结构非常容易。

假设我们有以下模型:

public class Hierarchy
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Hierarchy Parent { get; set; }
    public ICollection<Hierarchy> Children { get; set; }
}

然后是下面的代码

var hierarchy = db.Hierarchy.Include(e => e.Children).ToList();

将使用正确填充的ParentChildren 属性加载整个层次结构。

当您只需要加载层次结构的一部分时,就会出现参考文章中描述的问题,由于缺乏类似 CTE 的 LINQ 支持,这很困难。

【讨论】:

  • Include 也可能不需要,因为导航的目标类型与已加载的类型相同,因此无论如何关系修复都会填充它。
  • 有什么原因不能使用.Where,或者我遗漏了什么?
  • @eja 原因是如果你使用Where,它不会加载一些父母/孩子。 Include 没有帮助,因为它不是递归的。
  • @pantonis 那是因为代码将整个表格加载到一个平面列表中。要获取树(即根节点列表),您将应用 Where 仅获取根项,但加载所有实体及其导航属性之后。例如var tree = db.Hierarchy.Include(e =&gt; e.Children).ToList().Where(e =&gt; e.Parent == null).ToList();
  • @IvayloDimitrov 即使没有Include 用于跟踪查询,上述内容也适用于 3.0,但对于无跟踪查询似乎已损坏。最有可能通过以下重大更改No-tracking queries no longer perform identity resolution
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-13
  • 1970-01-01
  • 1970-01-01
  • 2012-10-02
  • 2011-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多