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.
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.
-
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 to share