Recursive selection via LINQ?

Possible duplicate:
linq to sql recursive query

I am stuck with creating a recursive selection via LINQ for my own link table.

enter image description here

I am using this class:

public class DivisionHierarchy
{
    public Division Division { get; set; }
    public IEnumerable<DivisionHierarchy> Divisions { get; set; }
}

      

and I created this function, but somehow it is infinite.

public IEnumerable<DivisionHierarchy> GetDivisionHierarchy(IEnumerable<Division> allDivisions, Division parentDivision)
{
    Guid? parentDivisionId = null;

    if (parentDivision != null)
         parentDivisionId = parentDivision.DivisionID;

    var childDivisions = allDivisions.Where(e => e.DivisionID == parentDivisionId);

    Collection<DivisionHierarchy> hierarchy = new Collection<DivisionHierarchy>();

    foreach (var div in childDivisions)
       hierarchy.Add(new DivisionHierarchy() { Division = div, Divisions = GetDivisionHierarchy(allDivisions, div) });

     return hierarchy;
}

      

Any hint where can I start?

Thank!

PS Are there any other ways to do this?


UPDATES based on http://www.scip.be/index.php?Page=ArticlesNET18#AsHierarchy

I found my mistakes.

There are two things to implement: 1. The root node must be created in the database.

enter image description here

  1. I changed the code a bit.

    Guid divisionID = Guid.Parse("5b487b3d-e9be-413f-b611-2fd7491e0d0d"); // Hardcoded somehow
    var rootDivision = db.Divisions.Where(i => i.ID == divisionID).FirstOrDefault();
    var divisionHierarchy = GetDivisionHierarchy(db.Divisions.AsEnumerable(), rootDivision);
    
          

    ...

     public IEnumerable<DivisionHierarchy> GetDivisionHierarchy(IEnumerable<Division> allDivisions, Division parentDivision)
            {
                Guid? parentDivisionId = null;
    
                if (parentDivision != null)
                    parentDivisionId = parentDivision.ID;
    
                var childDivisions = allDivisions.Where(division => division.DivisionID == parentDivisionId);
    
                Collection<DivisionHierarchy> hierarchy = new Collection<DivisionHierarchy>();
    
                foreach (var div in childDivisions)
                {
                    DivisionHierarchy divisionHierarchy = new DivisionHierarchy();
                    divisionHierarchy.Division = div;
                    divisionHierarchy.Divisions = GetDivisionHierarchy(allDivisions, div);
                    hierarchy.Add(divisionHierarchy);
                }
    
                return hierarchy;
            }
    
          

+3


source to share


1 answer


I would load divisions in a non-recursive way and then set up recursive relationships in code. Here's an example that does it in a lazy way.



public class Division
{
    public int ID { get; set; }
    public int DivisionID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }

    private static List<Division> _divisions;
    public static List<Division> Divisions
    {
        get
        {
            if (_divisions == null) {
                LoadAndSetUpDivisionsHierarchy();
            }
            return _divisions;
        }
    }

    private static Dictionary<int, Division> _divisionsByID;
    public static Dictionary<int, Division> DivisionsByID
    {
        get
        {
            if (_divisionsByID == null) {
                LoadAndSetUpDivisionsHierarchy();
            }
            return _divisionsByID;
        }
    }

    private static Division _root;
    public static Division Root
    {
        get
        {
            if (_root == null) {
                LoadAndSetUpDivisionsHierarchy();
            }
            return _root;
        }
    }

    private Division _parentDivision;
    public Division ParentDivision
    {
        get
        {
            if (_parentDivision == null && DivisionID != 0) {
                _parentDivision = DivisionsByID[DivisionID];

            }
            return _parentDivision;
        }
    }

    private List<Division> _subDivisions = new List<Division>();
    public List<Division> SubDivisions
    {
        get { return _subDivisions; }
    }

    private static void LoadAndSetUpDivisionsHierarchyHierarchy()
    {
        // Load the divisions in a non-recursive way using LINQ
        // (details not shown here).
        _divisions = LoadDivisions();

        // Add the divisions in a dictionary by id
        _divisionsByID = new Dictionary<int, Division>(_divisions.Count);
        foreach (Division division in _divisions) {
            _divisionsByID.Add(division.ID, division);
        }

        // Define sub-divisions and root division
        foreach (Division division in _divisions) {
            if (division.DivisionID == 0) {
                _root = division;
            } else if (division.ParentDivision != null) {
                division.ParentDivision.SubDivisions.Add(division);
            }
        }
    }

    private static List<Division> LoadDivisions()
    {
        throw new NotImplementedException();
    }
}

      

+4


source







All Articles