Пример #1
0
        public async Task <AccountHierarchy> AddNode(AccountHierarchy entity, bool autoCommit = true)
        {
            var sponsor = await _dbContext.AccountHierarchies
                          .Include(a => a.Children).FirstOrDefaultAsync(a => a.Id == entity.UplinkId);

            if (sponsor.Children.Count == 0)
            {
                entity.ParentId = sponsor.Id;
                entity.Leg      = sponsor.PlacementPreference == 2 ? 2 : 1;
            }
            else
            {
                Stopwatch sw = Stopwatch.StartNew();

                var sponsorTree = await _dbContext.AccountHierarchies
                                  .OrderBy(a => a.LevelPath.Length)
                                  .ThenBy(a => a.LevelPath)
                                  .Where(a => a.LevelPath.StartsWith(sponsor.LevelPath))
                                  .AsNoTracking()
                                  .ToListAsync();

                System.Console.WriteLine("Finding parent for entity " + entity.Name);
                var parent = await Task.Run(() => FindAvailableNodeInLoop(sponsorTree));

                System.Console.WriteLine($"Found parent {parent.Name} for entity {entity.Name}, took {sw.ElapsedMilliseconds} ms");

                entity.ParentId = parent.Id;
                entity.Leg      = parent.PlacementPreference;
            }

            var created = await this.AddToParent(entity, entity.ParentId, autoCommit);

            return(created);
        }
Пример #2
0
        private async Task <AccountHierarchy> AddToParent(AccountHierarchy entity, long?parentId, bool autoCommit = true)
        {
            if (!parentId.HasValue)
            {
                SqlHierarchyId parentLevel = SqlHierarchyId.GetRoot();
                entity.ParentId  = null;
                entity.UplinkId  = null;
                entity.LevelPath = parentLevel.ToString();
            }
            else
            {
                var parent = await _dbContext.AccountHierarchies.Where(x => x.Id == parentId)
                             .Include(x => x.Children)
                             .FirstOrDefaultAsync();

                SqlHierarchyId parentLevel = SqlHierarchyId.Parse(parent.LevelPath);


                var lastSibling = parent.Children.OrderByDescending(x => x.LevelPath).FirstOrDefault();

                string levelPath = null;

                if (entity.Leg == 2)
                {
                    if (lastSibling == null)
                    {
                        levelPath = parent.LevelPath + "2/";
                    }
                    else
                    {
                        SqlHierarchyId newLevel = parentLevel.GetDescendant(SqlHierarchyId.Parse(lastSibling.LevelPath), SqlHierarchyId.Null);
                        levelPath = newLevel.ToString();
                    }
                }
                else if (entity.Leg == 1)   // in any other case - put it on the left
                {
                    if (lastSibling == null)
                    {
                        levelPath = parent.LevelPath + "1/";
                    }
                    else
                    {
                        SqlHierarchyId newLevel = parentLevel.GetDescendant(SqlHierarchyId.Null, SqlHierarchyId.Parse(lastSibling.LevelPath));
                        levelPath = newLevel.ToString();
                    }
                }
                else
                {
                    throw new ArgumentOutOfRangeException("Leg", "Invalid value for leg: " + entity.Leg);
                }

                entity.LevelPath = levelPath;
                entity.ParentId  = parentId;
            }

            var result = (await _dbContext.AccountHierarchies.AddAsync(entity)).Entity;

            if (autoCommit)
            {
                await _dbContext.SaveChangesAsync();
            }

            return(result);
        }