【问题标题】:Find the depth level in parent-child hierarchy在父子层次结构中查找深度级别
【发布时间】:2016-09-30 09:52:57
【问题描述】:

我有如下表结构。

Id  |ParentId|  Name
--- |--------|-------
1   |NULL    |A
2   |1       |B
3   |2       |C
4   |3       |D

A 是 B 的父级,B 是 C 的父级,C 是 D 的父级。

我想计算父母每条记录有多少? 比如B指A,C指B,D指C。

在这种情况下,A 的深度级别为 0,B 为 1,C 为 2,D 为 3,具体取决于它们拥有的父级数量。

我可以使用递归函数来做到这一点,每次都查询记录是否有任何父项。我想以一种有效的方式使用 linq 查询来实现这一点。

【问题讨论】:

    标签: linq


    【解决方案1】:

    我认为在不过度计算、多个请求或临时 sql 表的情况下实现此目的的最佳方法是在 Dictionary 中一次选择所有表并在 C# 端计算父计数。

    如果你可以接受,可以使用这个函数和加法类来防止过度计算:

    public class ParentInfo
    {
        public int? ParentId { get; }
    
        public int? ParentCount { get; set; }
    
        public ParentInfo(int? parentId)
        {
            ParentId = parentId;
        }
    }
    
    private static int GetParentCount(int id, IDictionary<int, ParentInfo> conections)
    {
        if (!conections.ContainsKey(id))
            throw new InvalidDataException($"Id = {id} not found in connections");
        var info = conections[id];
        if (info.ParentCount.HasValue) return info.ParentCount.Value;
    
        var result = 0;
        if (info.ParentId.HasValue) result += 1 + GetParentCount(info.ParentId.Value, conections);
        info.ParentCount = result;
        return result;
    }
    

    然后您可以使用以下代码获得结果:

    var conections = table.ToDictionary(r => r.Id, r => new ParentInfo(r.ParentId));
    var result = conections.Select(c => new
    {
        Id = c.Key,
        ParentCount = GetParentCount(c.Key, conections)
    }).ToArray();
    

    【讨论】:

      【解决方案2】:

      我建议最好更改表结构并为模式添加另一个字段

      现在你可以在不使用递归函数的情况下以高性能的方式通过代码找到更深的层次

      using (var context = new Entities())
                  {
                      var foundNode = context.Trees.FirstOrDefault(w => w.Id == 1);
                      if (foundNode != null)
                      {
                          var deepNode = context.Trees.Where(w => w.Id != foundNode.Id && w.Pattern.StartsWith(foundNode.Pattern)).Select(s => new { s.Pattern.Length, s })
                              .GroupBy(g => g.Length).OrderByDescending(o => o.Key).Select(s => s.Select(sm => sm.s)).FirstOrDefault();
                      }
                  }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-06-25
        • 1970-01-01
        • 1970-01-01
        • 2021-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多