private static async Task __SetOneSelectionToAnother(
            NtwkDBContext context,
            int profileId,
            ProfileSelectedTagFlags from,
            ProfileSelectedTagFlags to
            )
        {
            IEnumerable <ProfileSelectedTag> fromAndToSelections =
                await context.ProfilesTagSelection
                .Where(pst => pst.BindedProfileID == profileId &&
                       (
                           from == (pst.Flags & from) ||
                           to == (pst.Flags & to))
                       )
                .ToListAsync();

            IEnumerable <ProfileSelectedTag> toSet = fromAndToSelections
                                                     .Where(pst => from == (pst.Flags & from) &&
                                                            to != (pst.Flags & to));
            IEnumerable <ProfileSelectedTag> toRemove = fromAndToSelections
                                                        .Where(pst => ProfileSelectedTagFlags.None == (pst.Flags ^ to));

            foreach (ProfileSelectedTag pst in toSet)
            {
                pst.Flags = pst.Flags | to;
            }

            context.ProfilesTagSelection.RemoveRange(toRemove);
            await context.SaveChangesAsync();
        }
        // building tree structure for node
        // public for testing purposes
        // should not be used outside this class
        public static async Task <List <NodeClosure> > __CreateNewNodeClosures(
            NtwkDBContext context,
            int?parentId,
            int nodeId
            )
        {
            List <NodeClosure> result;

            if (parentId != null)
            {
                result = await context.NodesClosureTable
                         .AsNoTracking()
                         .Where(c => c.DescendantID == parentId)
                         .Select(c => new NodeClosure
                {
                    ID           = 0,
                    AncestorID   = c.AncestorID,
                    DescendantID = nodeId,
                    Distance     = c.Distance + 1
                })
                         .ToListAsync();

                result.Add(new NodeClosure
                {
                    ID           = 0,
                    AncestorID   = nodeId,
                    DescendantID = nodeId,
                    Distance     = 0
                });
            }
            else
            {
                result = new[]
                {
                    new NodeClosure
                    {
                        ID           = 0,
                        AncestorID   = null,
                        DescendantID = nodeId,
                        Distance     = 0
                    },
                    new NodeClosure
                    {
                        ID           = 0,
                        AncestorID   = nodeId,
                        DescendantID = nodeId,
                        Distance     = 0
                    }
                }.ToList();
            }

            return(result);
        }
        private static async Task <Model.ViewModel.TagFilterData> GetProfileTagFilterData(
            NtwkDBContext context,
            int profileId,
            ProfileSelectedTagFlags flag
            )
        {
            var data = await context.ProfilesTagSelection.AsNoTracking()
                       .Where(pst => pst.BindedProfileID == profileId &&
                              flag == (pst.Flags & flag))
                       .Select(pst => new
            {
                tagID    = pst.TagID,
                nodesIDs = pst.Tag.Attachments.Select(a => a.Node.ID)
            })
                       .ToListAsync();

            return(new Model.ViewModel.TagFilterData()
            {
                TagsIDs = data.Select(d => d.tagID),
                NodesIDs = data.SelectMany(d => d.nodesIDs).Distinct()
            });
        }
        private static async Task __SetProfileTagSelection(
            NtwkDBContext context,
            int profileId,
            IEnumerable <int> tagIDs,
            ProfileSelectedTagFlags flag
            )
        {
            IEnumerable <int> ids = tagIDs as int[] ?? tagIDs.ToArray();
            IEnumerable <ProfileSelectedTag> currentSelection =
                await context.ProfilesTagSelection
                .Where(pts => pts.BindedProfileID == profileId)
                .ToListAsync();

            var currentWithFlag = currentSelection
                                  .Where(pts => flag == (pts.Flags & flag))
                                  .Select(pts => new
            {
                toStay = ids.Contains(pts.TagID),
                pts
            })
                                  .GroupBy(t => t.toStay)
                                  .Select(collection => new
            {
                collection.First().toStay,
                col = collection.Select(t => t.pts)
            })
                                  .ToArray();
            IEnumerable <int> toStay = currentWithFlag
                                       .SingleOrDefault(t => t.toStay)
                                       ?.col?.Select(pst => pst.TagID).ToList();
            IEnumerable <ProfileSelectedTag> toReset = currentWithFlag
                                                       .SingleOrDefault(t => !t.toStay)
                                                       ?.col;

            toStay  = toStay ?? (new List <int>());
            toReset = toReset ?? (new List <ProfileSelectedTag>());
            IEnumerable <ProfileSelectedTag> currentWithoutFlagToSet =
                currentSelection
                .Where(pts => flag != (pts.Flags & flag))
                .Where(pts => ids.Contains(pts.TagID))
                .ToList();

            foreach (ProfileSelectedTag pst in currentWithoutFlagToSet)
            {
                pst.Flags = pst.Flags | flag;
            }

            List <ProfileSelectedTag> toRemove = new List <ProfileSelectedTag>();

            foreach (ProfileSelectedTag pst in toReset)
            {
                if (ProfileSelectedTagFlags.None == (pst.Flags ^ flag))
                {
                    toRemove.Add(pst);
                }
                else
                {
                    pst.Flags = pst.Flags ^ flag;
                }
            }

            context.RemoveRange(toRemove);

            if ((toStay.Count() + currentWithoutFlagToSet.Count()) < ids.Count())
            {
                IEnumerable <int> alreadySetTags = new[]
                {
                    toStay,
                    currentWithoutFlagToSet.Select(pst => pst.TagID),
                }
                .SelectMany(t => t);
                IEnumerable <int> notSetTags = ids.Except(alreadySetTags);
                IEnumerable <ProfileSelectedTag> newSelections = notSetTags
                                                                 .Select(tagId => new ProfileSelectedTag
                {
                    ID              = 0,
                    Flags           = flag,
                    BindedProfileID = profileId,
                    TagID           = tagId
                });
                context.ProfilesTagSelection.AddRange(newSelections);
            }

            await context.SaveChangesAsync();
        }
 public EfDataSource(NtwkDBContext context)
 {
     _context = context;
 }