private static async Task <SearchResult <ClassifierGroup> > GetItemsByParent(DbContext db,
                                                                                     ClassifierType type, Guid?parentUid, ClassifierGroupSearchRequest request, bool calculateTotalCount)
        {
            var query = from item in db.GetTable <DbClassifier>()
                        where item.TypeUid == type.Uid && item.ParentUid == parentUid
                        // orderby item.StatusCode, item.Code, item.Name
                        select item;

            var data = query
                       .Apply(request, x => x.Code)
                       .Select(x => new ClassifierGroup
            {
                Uid       = x.Uid,
                Code      = x.Code,
                Name      = x.Name,
                ParentUid = x.ParentUid
            })
                       .ToList();

            var result = new SearchResult <ClassifierGroup> {
                Rows = data
            };

            if (calculateTotalCount)
            {
                result.TotalCount = await query.CountAsync();
            }

            if (request.ExpandSingleChild && result.Rows.Count == 1)
            {
                var singleChild = data[0];

                var children = await GetItemsByParent(db, type, singleChild.Uid, request, false);

                singleChild.Children = children.Rows;
            }

            return(result);
        }
        private static async Task <SearchResult <ClassifierGroup> > GetGroupsByFocus(DbContext db,
                                                                                     ClassifierType type, ClassifierTree tree, ClassifierGroupSearchRequest request, CancellationToken cancellationToken)
        {
            // get all parent uids of focused item
            var path = await(
                from focus in db.GetTable <DbClassifierGroup>()
                join closureUp in db.GetTable <DbClassifierClosure>() on focus.Uid equals closureUp.ChildUid
                join item in db.GetTable <DbClassifierGroup>() on closureUp.ParentUid equals item.Uid
                where /*focus.TypeUid == type.Uid &&*/ focus.Uid == request.FocusUid
                orderby closureUp.Level descending
                select item.ParentUid)
                       .ToListAsync(cancellationToken);

            SearchResult <ClassifierGroup> result = null;

            List <ClassifierGroup> currentLevel = null;

            foreach (var parentUid in path)
            {
                if (parentUid == request.ParentUid)
                {
                    // found requested parent, init result and starting level
                    result = new SearchResult <ClassifierGroup>
                    {
                        Rows = currentLevel = new List <ClassifierGroup>()
                    };
                }

                // if current level is not already inited
                if (currentLevel == null)
                {
                    continue;
                }

                // try to move to deeper level...
                if (parentUid.HasValue)
                {
                    var parent = currentLevel.SingleOrDefault(x => x.Uid == parentUid);

                    if (parent != null)
                    {
                        parent.Children = currentLevel = new List <ClassifierGroup>();
                    }
                }

                // ... and load children
                var chldrn = await GetGroupsByParent(db, type, tree, parentUid, request, false);

                currentLevel.AddRange(chldrn.Rows);
            }

            return(result);
        }
        private static async Task <SearchResult <ClassifierGroup> > GetGroupsByParent(DbContext db,
                                                                                      ClassifierType type, ClassifierTree tree, Guid?parentUid, ClassifierGroupSearchRequest request, bool calculateTotalCount)
        {
            var query = from tree1 in db.GetTable <DbClassifierTree>()
                        join item in db.GetTable <DbClassifierGroup>() on tree.Uid equals item.TreeUid
                        where tree1.Uid == tree.Uid && tree1.TypeUid == type.Uid && item.ParentUid == parentUid
                        select item;

            var data = query
                       .Apply(request, x => x.Code)
                       .Select(x => new ClassifierGroup
            {
                Uid       = x.Uid,
                Code      = x.Code,
                Name      = x.Name,
                TreeUid   = x.TreeUid,
                ParentUid = x.ParentUid
            })
                       .ToList();

            var result = new SearchResult <ClassifierGroup> {
                Rows = data
            };

            if (calculateTotalCount)
            {
                result.TotalCount = await query.CountAsync();
            }

            if (request.ExpandSingleChild && data.Count == 1)
            {
                var singleChild = data[0];

                var children = await GetGroupsByParent(db, type, tree, singleChild.Uid, request, false);

                singleChild.Children = children.Rows;
            }

            return(result);
        }