private TaskDescription UpdateTask(TaskDescription taskDescription, TaskRequest taskRequest) { using (var db = new Db.DataContext()) { var taskDb = db.Task.Where(x => x.UniqueKey == taskRequest.UniqueKey).Include(x => x.TaskSchedules).FirstOrDefault(); if (taskDb == null) { taskDb = new Db.Task() { Name = taskRequest.Name, Description = taskRequest.Description, IsEnabled = null, TaskSchedules = new List <Db.TaskSchedule>(), UniqueKey = taskRequest.UniqueKey }; db.Task.Add(taskDb); db.SaveChanges(); } taskDb.Name = taskRequest.Name; taskDb.Description = taskRequest.Description; if (!taskRequest.TaskOptions.HasFlag(TaskOptions.AllowDisabling)) { taskDb.IsEnabled = null; } if (!taskRequest.TaskOptions.HasFlag(TaskOptions.AllowManualSchedule) && taskDb.TaskSchedules.Count > 0) { db.TaskSchedule.RemoveRange(taskDb.TaskSchedules); taskDb.TaskSchedules.Clear(); } db.SaveChanges(); var schedules = new List <TaskSchedule>(); foreach (var scheduleDb in taskDb.TaskSchedules) { TaskSchedule taskSchedule = null; if (scheduleDb.DateTimeFixed.HasValue) { taskSchedule = new TaskFixedTimeSchedule(new DateTimeOffset(scheduleDb.DateTimeFixed.Value.Ticks, TimeSpan.Zero)); } else if (!string.IsNullOrEmpty(scheduleDb.Cron)) { taskSchedule = new TaskCronSchedule(scheduleDb.Cron); } if (taskSchedule == null) { continue; } taskSchedule.IsEnabled = scheduleDb.IsEnabled; schedules.Add(taskSchedule); } taskDescription.Id = taskDb.Id; taskDescription.Name = taskRequest.Name; taskDescription.Description = taskRequest.Description; taskDescription.ExecutionLambda = taskRequest.ExecutionLambda; taskDescription.IsConfirmed = true; taskDescription.UniqueKey = taskRequest.UniqueKey; taskDescription.IsEnabled = taskDb.IsEnabled ?? taskRequest.IsEnabled; taskDescription.TaskOptions = taskRequest.TaskOptions; taskDescription.Schedules = new ReadOnlyCollection <TaskSchedule>(taskRequest.Schedules ?? new List <TaskSchedule>()); taskDescription.ManualSchedules = new ReadOnlyCollection <TaskSchedule>(schedules.GroupBy(x => x.GetUniqueKey()).Select(x => x.First()).ToList()); taskDescription.JournalOptions = taskRequest.JournalOptions; } return(taskDescription); }
/// <summary> /// Позволяет изменить список дополнительных правил задачи. /// </summary> /// <param name="taskDescription">Зарегистрированная задача.</param> /// <param name="scheduleList">Список правил задачи.</param> /// <exception cref="ArgumentNullException">Возникает, если <paramref name="taskDescription"/> равен null.</exception> /// <exception cref="InvalidOperationException">Возникает, если задача не зарегистрирована.</exception> /// <exception cref="InvalidOperationException">Возникает, если для задачи запрещено изменение списка правил (см. <see cref="TaskOptions.AllowManualSchedule"/>).</exception> public void SetTaskManualScheduleList(TaskDescription taskDescription, List <TaskSchedule> scheduleList) { if (taskDescription == null) { throw new ArgumentNullException(nameof(taskDescription)); } if (!_taskList.TryGetValue(taskDescription.UniqueKey, out var taskDescription2)) { throw new InvalidOperationException("Неизвестная задача."); } if (!taskDescription2.TaskOptions.HasFlag(TaskOptions.AllowManualSchedule)) { throw new InvalidOperationException("Для задачи запрещено изменение списка правил."); } if (scheduleList?.GroupBy(x => x.GetUniqueKey()).Any(x => x.Count() > 1) ?? false) { throw new ArgumentException("В списке есть повторяющиеся правила запуска.", nameof(scheduleList)); } try { var schedules = scheduleList?.ToDictionary(x => x.GetUniqueKey(), x => x); var collection = new ReadOnlyCollection <TaskSchedule>(scheduleList ?? new List <TaskSchedule>()); using (var db = new Db.DataContext()) { var list = db.TaskSchedule.Where(x => x.IdTask == taskDescription2.Id).ToList(); var listToRemove = list.Where(x => !schedules.ContainsKey(x.GetUniqueKey())).ToList(); db.TaskSchedule.RemoveRange(listToRemove); var isChanged = listToRemove.Count > 0; list.Where(x => schedules.ContainsKey(x.GetUniqueKey())).ForEach(x => { isChanged = isChanged || x.IsEnabled != schedules[x.GetUniqueKey()].IsEnabled; x.IsEnabled = schedules[x.GetUniqueKey()].IsEnabled; }); schedules.ForEach(pair => { if (!list.Any(x => x.GetUniqueKey() == pair.Key)) { if (pair.Value is TaskCronSchedule taskCronSchedule) { isChanged = true; db.TaskSchedule.Add(new Db.TaskSchedule() { IdTask = taskDescription2.Id, IsEnabled = pair.Value.IsEnabled, Cron = taskCronSchedule.CronExpression }); } else if (pair.Value is TaskFixedTimeSchedule taskFixedTimeSchedule) { isChanged = true; db.TaskSchedule.Add(new Db.TaskSchedule() { IdTask = taskDescription2.Id, IsEnabled = pair.Value.IsEnabled, DateTimeFixed = taskFixedTimeSchedule.DateTime.UtcDateTime }); } } }); if (isChanged) { db.SaveChanges(); } taskDescription2.ManualSchedules = collection; taskDescription.ManualSchedules = collection; PrepareTaskSchedules(taskDescription2); } } catch (Exception ex) { this.RegisterEvent(Journaling.EventType.CriticalError, "Ошибка во время сохранения списка правил", null, ex); throw new Exception("Неожиданная ошибка во время сохранения списка правил."); } }