Most efficient method of self referencing tree using Entity Framework

后端 未结 6 2105
萌比男神i
萌比男神i 2020-11-28 02:12

So I have a SQL table which is basically

ID, ParentID, MenuName, [Lineage, Depth]

The last two columns are auto-computed to help with sear

6条回答
  •  迷失自我
    2020-11-28 02:37

    I've already spent a while trying to fix a bug in your solution. The stored procedure really don't generate children, grandchildren, etc. Below you will find fixed stored procedure:

    CREATE PROCEDURE dbo.UpdateHierarchy AS
    BEGIN
      DECLARE @sql nvarchar(MAX)
    
      SET @sql = ''
      SET @sql = @sql + 'WITH Hierachy(ChildId, ParentId) AS ( '
      SET @sql = @sql + 'SELECT t.Id, t.ParentId FROM dbo.Tree t '
      SET @sql = @sql + 'UNION ALL '
      SET @sql = @sql + 'SELECT h.ChildId, t.ParentId FROM dbo.Tree t '
      SET @sql = @sql + 'INNER JOIN Hierachy h ON t.Id = h.ParentId) '
      SET @sql = @sql + 'INSERT INTO dbo.TreeHierarchy (ChildId, ParentId) ( '
      SET @sql = @sql + 'SELECT DISTINCT ChildId, ParentId FROM Hierachy WHERE ParentId IS NOT NULL '
      SET @sql = @sql + 'EXCEPT SELECT t.ChildId, t.ParentId FROM dbo.TreeHierarchy t '
      SET @sql = @sql + ') '
    
      EXECUTE (@sql)
    END
    

    Mistake: wrong reference. Translating @hazzik code it was:

      SET @sql = @sql + 'SELECT t.ChildId, t.ParentId FROM dbo.Tree t '
    

    but should be

      SET @sql = @sql + 'SELECT h.ChildId, t.ParentId FROM dbo.Tree t '
    

    also I've added code that allows you to update TreeHierarchy table not only when you will populate it.

      SET @sql = @sql + 'EXCEPT SELECT t.ChildId, t.ParentId FROM dbo.TreeHierarchy t '
    

    And the magic. This procedure or rather TreeHierarchy allows you to load Children just by including Ancestors (not Children and not Descendants).

     using (var context = new YourDbContext())
     {
          rootNode = context.Tree
               .Include(x => x.Ancestors)
               .SingleOrDefault(x => x.Id == id);
     } 
    

    Now the YourDbContext will return a rootNode with loaded children, children of rootName's children (grandchildren), and so on.

提交回复
热议问题