【问题标题】:Entity Framework Core Parent/Child Clean query with multi level child [duplicate]具有多级子级的实体框架核心父/子清理查询[重复]
【发布时间】:2020-06-12 17:54:46
【问题描述】:

我在清理查询我的父子时遇到问题,而不在列表的根目录重复子项。

对象

 public class Office
    {

        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
        public bool Inactive { get; set; }
        public int? ParentId { get; set; }
        [ForeignKey("ParentId")]
        public Office Parent { get; set; }
        [InverseProperty("Parent")]
        public virtual ICollection<Office> Children { get; set; }
    }
}

查询

public async Task<IEnumerable<Office>> GetOffices()
        {
            return await _context.Offices.Where(os => !os.Inactive)
                   .Include(o => o.Parent)
                   .Include(o => o.Children).ToListAsync();
        }

结果

 {
        "id": 5,
        "name": "AA",
        "inactive": false,
        "parentId": null,
        "parent": null,
        "children": []
    },
    {
        "id": 10,
        "name": "BAA",
        "inactive": false,
        "parentId": 2,
        "parent": {
            "id": 2,
            "name": "BA",
            "inactive": false,
            "parentId": null,
            "parent": null,
            "children": []
        },
        "children": [
            {
                "id": 1011,
                "name": "BAAA",
                "inactive": false,
                "parentId": 10,
                "children": []
            }
        ]
    },
    {
        "id": 1011,
        "name": "BAAA",
        "inactive": false,
        "parentId": 10,
        "parent": {
            "id": 10,
            "name": "BAA",
            "inactive": false,
            "parentId": 2,
            "parent": {
                "id": 2,
                "name": "BA",
                "inactive": false,
                "parentId": null,
                "parent": null,
                "children": []
            },
            "children": []
        },
        "children": []
    },
,
    {
        "id": 2,
        "name": "BA",
        "inactive": false,
        "parentId": null,
        "parent": null,
        "children": [
            {
                "id": 10,
                "name": "BAA",
                "inactive": false,
                "parentId": 2,
                "children": [
                    {
                        "id": 1011,
                        "name": "BAAA",
                        "inactive": false,
                        "parentId": 10,
                        "children": []
                    }
                ]
            }
        ]
    }

这在根级别也有子对象,所以我尝试了这个

public async Task<IEnumerable<Office>> GetOffices()
        {
            return await _context.Offices.Where(os => !os.Inactive && !os.ParentId.HasValue).Include(o => o.Parent).Include(o => o.Children).ToListAsync();
        }

这是另一个查询的结果

{
        "id": 5,
        "name": "AA",
        "inactive": false,
        "parentId": null,
        "parent": null,
        "children": []
    },
    {
        "id": 2,
        "name": "BA",
        "inactive": false,
        "parentId": null,
        "parent": null,
        "children": [
            {
                "id": 10,
                "name": "BAA",
                "inactive": false,
                "parentId": 2,
                "children": null
            }
        ]
    }

这忽略了 id 1010 BAAA 子对象。理想情况下,我希望它作为

{
        "id": 5,
        "name": "AA",
        "inactive": false,
        "parentId": null,
        "parent": null,
        "children": []
    },
    {
        "id": 2,
        "name": "BA",
        "inactive": false,
        "parentId": null,
        "parent": null,
        "children": [
            {
                "id": 10,
                "name": "BAA",
                "inactive": false,
                "parentId": 2,
                "children": [
                    {
                        "id": 1011,
                        "name": "BAAA",
                        "inactive": false,
                        "parentId": 10,
                        "children": []
                    }
                ]
            }
        ]
    }

无论我如何堆叠查询,我似乎都无法以这种方式显示。有没有办法调整查询以允许此查询或简单的后查询命令仅修剪作为子级的根级别对象?

【问题讨论】:

    标签: c# .net-core entity-framework-core hierarchical-data


    【解决方案1】:

    如果您想获取有限数量的子级别(本例中为 2 个),您可以尝试:

    await _context.Offices
        .Where(os => !os.Inactive && !os.ParentId.HasValue)
        .Include(o => o.Parent)
        .Include(o => o.Children)
        .ThenInclude(o => o.Children)
        .ToListAsync()
    

    【讨论】:

    • 谢谢。 then-include 是我所缺少的。虽然关卡是动态的,但我会设置 5 个关卡,因为它永远不会超过那个。
    • 跟进问题。我的包含不过滤非活动。我可以在包含的内容中使用不活动的过滤器吗?
    • @Ramious 否,除非此功能在 .NET 5.0 中随 EF 一起提供。此外,如果您只想获取所有活动的层次结构,您可以尝试(await _context.Offices.Where(os =&gt; !os.Inactive).ToListAsync()).Where(os =&gt; !os.ParentId.HasValue).ToList();
    • 我试过了,但我在第三级有一个非活动的 true 并且仍然出现在你的新查询中。
    • @Ramious 此查询不会获取任何非活动数据。仔细看看 - 这里没有包含。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    相关资源
    最近更新 更多