private static async Task <ICollection <Tuple <ICollection <ItemRelationPreview>, IItemSideRunner> > > ProcessRelations(ICollection <ItemRelationPreview> relations, IItemSideRunner runItemSide, SynchronizationAction action, int level = 1) { if (!relations.Any()) { return(Enumerable.Empty <Tuple <ICollection <ItemRelationPreview>, IItemSideRunner> >().ToList()); } List <Tuple <ICollection <ItemRelationPreview>, IItemSideRunner> > nextLevels = new List <Tuple <ICollection <ItemRelationPreview>, IItemSideRunner> >(); foreach (var rel in relations) { var runSubItem = runItemSide.SubItems.Single(si => si.Id == rel.Id); var runSubItemSide = runSubItem.SideRunners.First(); var runSubSide = runSubItemSide.Side; var subMap = new Func <IItemRunner, IItemSideRunner, object>((i, s) => { if (runSubSide.Comparator.GetItemTypes().Item1.GetTypeInfo().IsAssignableFrom(runSubItem.MasterItem.GetType().GetTypeInfo())) { // Master is A in this comparator if (runSubItem.MasterItem != null) { return(runSubSide.Comparator.MapAToB(i.MasterItem, s.SideItem)); } } else { // Master is B in this comparator if (runSubItem.MasterItem != null) { return(runSubSide.Comparator.MapBToA(i.MasterItem, s.SideItem)); } } return(null); }); if (rel.IsEnabled && rel.Action == action && rel.Action == SynchronizationAction.Insert) { var newItem = subMap(runSubItem, runSubItemSide); await runSubSide.InsertAsync(newItem); foreach (var subItem in runSubItemSide.SubItems) { subItem.SideRunners.First().Side.Source = newItem; } } else if (rel.IsEnabled && rel.Action == action && rel.Action == SynchronizationAction.Update) { var newItem = subMap(runSubItem, runSubItemSide); await runSubSide.UpdateAsync(newItem); foreach (var subItem in runSubItemSide.SubItems) { subItem.SideRunners.First().Side.Source = newItem; } } else if (rel.IsEnabled && rel.Action == action && rel.Action == SynchronizationAction.Delete) { await runSubSide.DeleteAsync(runSubItemSide.SideItem); } if (rel.Relations.Any()) { nextLevels.Add(new Tuple <ICollection <ItemRelationPreview>, IItemSideRunner>(rel.Relations, runSubItemSide)); } } return(nextLevels); }
ProcessRelations(ICollection <ItemRelationPreview> relations, IItemSideRunner runItemSide, SynchronizationAction action) { if (!relations.Any()) { return(Enumerable.Empty <(ICollection <ItemRelationPreview>, IItemSideRunner)>().ToList(), () => Task.FromResult(0)); } var levels = new List <(ICollection <ItemRelationPreview>, IItemSideRunner)>(); var processActions = new List <Func <Task> >(); foreach (var rel in relations) { var runSubItem = runItemSide.SubItems.Single(si => si.Id == rel.Id); var runSubItemSide = runSubItem.SideRunners.First(); // ----- processActions.Add(new Func <Task>(async() => { var runSubSide = runSubItemSide.Side; var subMap = new Func <IItemRunner, IItemSideRunner, object>((i, s) => { if (runSubSide.Comparator.GetItemTypes().typeA.GetTypeInfo().IsAssignableFrom(runSubItem.MasterItem.GetType().GetTypeInfo())) { // Master is A in this comparator if (runSubItem.MasterItem != null) { return(runSubSide.Comparator.MapAToB(i.MasterItem, s.SideItem)); } } else { // Master is B in this comparator if (runSubItem.MasterItem != null) { return(runSubSide.Comparator.MapBToA(i.MasterItem, s.SideItem)); } } return(null); }); if (rel.IsEnabled && rel.Action == action && rel.Action == SynchronizationAction.Insert) { var newItem = subMap(runSubItem, runSubItemSide); await runSubSide.InsertAsync(newItem); foreach (var subItem in runSubItemSide.SubItems) { subItem.SideRunners.First().Side.Source = newItem; } } else if (rel.IsEnabled && rel.Action == action && rel.Action == SynchronizationAction.Update) { var newItem = subMap(runSubItem, runSubItemSide); await runSubSide.UpdateAsync(newItem); foreach (var subItem in runSubItemSide.SubItems) { subItem.SideRunners.First().Side.Source = newItem; } } else if (rel.IsEnabled && rel.Action == action && rel.Action == SynchronizationAction.Delete) { await runSubSide.DeleteAsync(runSubItemSide.SideItem); } })); // ----- if (rel.Relations.Any()) { levels.Add((rel.Relations, runSubItemSide)); } } return(levels, processActions.Transform(acts => new Func <Task>(async() => { foreach (var act in acts) { await act(); } }))); }