private static SelectStatement CreateSelectFromLevelQuery(IEntity rootEntity, DbRelation recursiveRelation, SearchCondition leafFilter, int level, LevelQuerySelectList itemsToSelect)
        {
            if (level > Settings.GenericHierarchicalQueryExecutorMaxLevel)
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Messages.GenericHierarchicalQueryExecutor_MaxLevelReachedFormat, Settings.GenericHierarchicalQueryExecutorMaxLevel));

            // Target level table must be child table because that is the table which is used in leafFilter.
            // If leaf filter is used then the we must ensure that proper table name is used for target table.
            IDbTable targetLevelTable;
            if (leafFilter != null && !leafFilter.IsEmpty)
                targetLevelTable = recursiveRelation.Child;
            else
                targetLevelTable = rootEntity.Table.Clone("L" + level);

            SelectStatement selectFromTargetLevel = new SelectStatement(targetLevelTable);
            CreateSelectListItems(itemsToSelect, targetLevelTable, selectFromTargetLevel);

            if (leafFilter != null && !leafFilter.IsEmpty)
                selectFromTargetLevel.Where.Add(leafFilter);

            IDbTable prevLevel = targetLevelTable;
            for (int parentLevel = level - 1; parentLevel >= 0; parentLevel--)
            {
                IDbTable nextLevel = rootEntity.Table.Clone("L" + parentLevel);
                DbRelation joinLevels = JoinLevelsInSubTree(prevLevel, nextLevel, recursiveRelation);
                selectFromTargetLevel.Relations.Add(joinLevels, false, false);
                prevLevel = nextLevel;
            }

            IDbTable subTreeRoot = prevLevel;
            foreach (IDbColumn rootPkPart in subTreeRoot.PrimaryKey)
                selectFromTargetLevel.Where.Add(rootPkPart, rootEntity.GetField(rootPkPart));

            return selectFromTargetLevel;
        }
 private static void CreateSelectListItems(LevelQuerySelectList itemsToSelect, IDbTable targetLevelTable, SelectStatement selectFromTargetLevel)
 {
     if (itemsToSelect == LevelQuerySelectList.AllColumns)
         selectFromTargetLevel.SelectList.Add(targetLevelTable.Columns);
     else if (itemsToSelect == LevelQuerySelectList.Count)
         selectFromTargetLevel.SelectList.Add(AggregateFunctionFactory.Count("nodeCount"));
     else if (itemsToSelect == LevelQuerySelectList.PrimaryKey)
         selectFromTargetLevel.SelectList.Add(targetLevelTable.PrimaryKey);
 }