/// <summary> /// Sauvegarde les actions spécifiées. /// </summary> /// <param name="context">Le contexte.</param> /// <param name="allScenarios">Tous les scénarios liés.</param> /// <param name="updatedScenario">Le scénario qui a été mis à jour.</param> /// <param name="recursive"><c>true</c> pour appliquer les changements récursivement sur les scénarios dérivés.</param> public static Task SaveAcquireData(KsmedEntities context, Scenario[] allScenarios, Scenario updatedScenario, bool recursive) { KAction[] actionsToDelete; IList <KAction> actionsWithOriginal; if (recursive) { ActionsRecursiveUpdate.UpdateActions(context, updatedScenario, allScenarios, out actionsToDelete, out actionsWithOriginal); } else { actionsWithOriginal = null; actionsToDelete = updatedScenario.Actions.Where(a => a.IsMarkedAsDeleted).ToArray(); updatedScenario.CriticalPathIDuration = ActionsTimingsMoveManagement.GetInternalCriticalPathDuration(updatedScenario); } // Consolider les solutions vides EnsureEmptySolutionExists(updatedScenario); UdpateSolutionsApprovedState(updatedScenario); KAction[] allActions = allScenarios .SelectMany(s => s.Actions) .Where(a => a.IsNotMarkedAsUnchanged) .ToArray(); foreach (KAction action in allActions) { if (!action.IsReduced) { ApplyNewReduced(action, KnownActionCategoryTypes.I); } context.KActions.ApplyChanges(action); context.KActionsReduced.ApplyChanges(action.Reduced); } if (actionsWithOriginal != null) { foreach (KAction action in actionsWithOriginal) { SetActionsOriginalReference(context, action); } } foreach (Scenario scenario in allScenarios.Where(s => s.IsNotMarkedAsUnchanged)) { context.Scenarios.ApplyChanges(scenario); } context.Scenarios.ApplyChanges(updatedScenario); foreach (KAction action in actionsToDelete) { action.Predecessors.Clear(); action.Successors.Clear(); action.MarkAsDeleted(); // Ne pas appeler ApplyChanges car les self tracking le gèrent mal (plantage lors de la sauvegarde) // Ajouter l'action au contexte si elle n'y est pas attachée if (!context.ObjectStateManager.TryGetObjectStateEntry(action, out ObjectStateEntry entry)) { context.AddObject(KsmedEntities.KActionsEntitySetName, action); context.ObjectStateManager.ChangeObjectState(action, EntityState.Deleted); } else { context.KActions.DeleteObject(action); } } // Vérifier que tout est correct if (recursive) { ActionsTimingsMoveManagement.DebugCheckAllWBS(allScenarios.Where(s => s.IsNotMarkedAsUnchanged)); } return(context.SaveChangesAsync()); }
/// <summary> /// Sauvegarde les actions spécifiées. /// </summary> /// <param name="context">Le contexte.</param> /// <param name="allScenarios">Tous les scénarios liés.</param> /// <param name="updatedScenario">Le scénario qui a été mis à jour.</param> /// <param name="recursive"><c>true</c> pour appliquer les changements récursivement sur les scénarios dérivés.</param> public async Task <Scenario> SaveAcquireData(KsmedEntities context, Scenario[] allScenarios, Scenario updatedScenario, bool recursive) { try { // Don't insert a thumbnail that already exists var actionsWithNewThumbnail = updatedScenario.Actions.Where(_ => (_.IsMarkedAsAdded && _.Thumbnail != null) || (_.IsMarkedAsModified && _.ChangeTracker.ModifiedValues.ContainsKey(nameof(KAction.Thumbnail)) && _.Thumbnail != null)); foreach (var action in actionsWithNewThumbnail) { CloudFile thumbnail = updatedScenario.Actions.Where(_ => _.Thumbnail != null && _.ActionId != action.ActionId).Select(_ => _.Thumbnail).FirstOrDefault(_ => _.Hash == action.ThumbnailHash); if (thumbnail == null) { thumbnail = await context.CloudFiles.SingleOrDefaultAsync(_ => _.Hash == action.Thumbnail.Hash); } if (thumbnail != null) { action.Thumbnail = thumbnail; } } KAction[] actionsToDelete; IList <KAction> actionsWithOriginal; if (recursive) { ActionsRecursiveUpdate.UpdateActions(context, updatedScenario, allScenarios, out actionsToDelete, out actionsWithOriginal); } else { actionsWithOriginal = null; actionsToDelete = updatedScenario.Actions.Where(a => a.IsMarkedAsDeleted).ToArray(); updatedScenario.CriticalPathIDuration = ActionsTimingsMoveManagement.GetInternalCriticalPathDuration(updatedScenario); } // Consolider les solutions vides EnsureEmptySolutionExists(updatedScenario); UdpateSolutionsApprovedState(updatedScenario); // Update InheritedAction if original will be deleted var actionIdsToDelete = actionsToDelete.Select(_ => _.ActionId).ToList(); var inheritedActions = await context.KActions .Where(_ => _.OriginalActionId != null && actionIdsToDelete.Contains(_.OriginalActionId.Value)) .ToListAsync(); foreach (var inheritedAction in inheritedActions) { inheritedAction.OriginalActionId = null; context.KActions.ApplyChanges(inheritedAction); } KAction[] allActions = allScenarios .SelectMany(s => s.Actions) .Where(a => a.IsNotMarkedAsUnchanged) .ToArray(); foreach (KAction action in allActions) { if (!action.IsReduced) { ApplyNewReduced(action, KnownActionCategoryTypes.I); } context.KActions.ApplyChanges(action); context.KActionsReduced.ApplyChanges(action.Reduced); } if (actionsWithOriginal != null) { foreach (KAction action in actionsWithOriginal) { SetActionsOriginalReference(context, action); } } foreach (Scenario scenario in allScenarios.Where(s => s.IsNotMarkedAsUnchanged)) { context.Scenarios.ApplyChanges(scenario); } context.Scenarios.ApplyChanges(updatedScenario); foreach (KAction action in actionsToDelete) { action.Predecessors.Clear(); action.Successors.Clear(); action.MarkAsDeleted(); // Ne pas appeler ApplyChanges car les self tracking le gèrent mal (plantage lors de la sauvegarde) // Ajouter l'action au contexte si elle n'y est pas attachée if (!context.ObjectStateManager.TryGetObjectStateEntry(action, out ObjectStateEntry entry)) { context.AddObject(KsmedEntities.KActionsEntitySetName, action); context.ObjectStateManager.ChangeObjectState(action, EntityState.Deleted); } else { context.KActions.DeleteObject(action); } } // Vérifier que tout est correct if (recursive) { ActionsTimingsMoveManagement.DebugCheckAllWBS(allScenarios.Where(s => s.IsNotMarkedAsUnchanged)); } await context.SaveChangesAsync(); return(updatedScenario); } catch (Exception ex) { TraceManager.TraceError(ex, $"Error while saving scenario {updatedScenario.ScenarioId}"); throw; } }