首页 > 解决方案 > Entity Framework Core 递归加载自引用结果

问题描述

我有一张这样的桌子,

public class Asset
{

    public int id_asset { get; set; }
    public int id_user { get; set; }
    public int id_parent_asset { get; set; }
    public string name { get; set; }

    public virtual Asset Parent_Asset { get; set; }
    public virtual ICollection<Asset> Child_Assets { get; set; }
    public virtual User User { get; set; }
}

我想获得资产的所有子资产。我尝试了以下代码,

context.Asset.Where(o => o.name.Contains("Root")).Include(o => o.Child_Assets ).FirstOrDefault();

但它只包含一个级别的孩子。我需要获得所有级别。我不知道我应该获得多少级别,所以我需要一个递归方法,或者也许已经有一种方法可以做到这一点。

有谁知道我该如何处理这个问题。

标签: entity-framework-coreeager-loadingasp.net-core-3.1

解决方案


我遇到了同样的问题,并且能够使用延迟加载而不是急切加载来解决它。这可能适合您,也可能不适合您。

使用延迟加载,您无需在查询数据库时指定要加载的导航属性(无需 .Include 调用)。EF Core 将在您访问它们时自动为您加载相关实体。即从上下文中获取根资产,它的孩子将在那里。

要使用延迟加载,您需要添加 Microsoft.EntityFrameworkCore.Proxies nuget 包,然后.UseLazyLoadingProxies()在配置上下文时调用。有关详细信息,请参阅文档https://docs.microsoft.com/en-us/ef/core/querying/related-data#lazy-loading

另请注意,要使魔法发生,加载实体的上下文需要了解相关实体(您的案例中的子资产)。它不会去查询数据库中的子资产,但如果它在内存中有它们,它会将它们链接起来。因此,在您的情况下,您将需要加载所有资产,然后获取根资产及其子资产及其子资产。

如果您使用多个上下文,您可能会遇到问题。假设资产被加载到一个上下文中而用户被加载到另一个上下文中,在这种情况下 root.User 将为空,因为用于加载根资产的上下文没有内存中的用户。


推荐阅读