using System; using System.Data.Entity.Core.Objects; using System.Linq; using Neo.Afx.ComponentModel; using System.Threading; namespace Neo.Afx.WinService.Workflows { public class WorkflowServiceDatabase : Database { public WorkflowServiceDatabase(string connectionString) : base(new WorkflowServiceContext(connectionString)) { } #region GetHandlers public IQueryable GetHandlers() { return from q in Context.WorkflowTaskHandlers.Include("WorkflowTaskHandlerSettings") where !q.IsCancelled select q; } #endregion #region GetTasks public IQueryable GetTasks() { return from q in Context.WorkflowInstanceTasks.Include("WorkflowTemplateStep") orderby q.CreatedDate where q.WorkflowInstanceTaskStatusID == (short)WorkflowInstanceTaskStatusEnum.Outstanding && q.WorkflowTemplateStep.WorkflowTemplateStepTypeID == (short)WorkflowTemplateStepTypeEnum.Automated select q; } #endregion #region UpdateTaskStatus public bool UpdateTaskStatus(long workflowInstanceTaskID, short workflowInstanceTaskStatusID, string completedByUserName, string comments, out string error) { var errorMessage = new ObjectParameter("ErrorMessage", typeof(string)); var tryActionCount = 0; TryAction: try { Context.Pr_WorkflowInstanceTaskAction(workflowInstanceTaskID, workflowInstanceTaskStatusID, completedByUserName, -1, comments, errorMessage); error = errorMessage.Value.ToStringSafe(); } catch (Exception ex) { var message = GetInnermostMessage(ex); error = message; if (!String.IsNullOrEmpty(message) && message.ToLower().Contains("deadlock") && tryActionCount < 5) { Random rnd = new Random(); Thread.Sleep(rnd.Next(2000, 4000)); tryActionCount++; goto TryAction; } else { throw ex; } } return string.IsNullOrEmpty(error); } #endregion #region UpdateTaskStatusFailover public void UpdateTaskStatusFailover(long workflowInstanceTaskID, string error, long updatedByID) { Context.Pr_WorkflowInstanceTaskActionFailover(workflowInstanceTaskID, error, updatedByID); } #endregion #region RaiseException public bool RaiseException(long workflowInstanceTaskID, string completedByUserName, string comments, out string error) { var errorMessage = new ObjectParameter("ErrorMessage", typeof(string)); var tryActionCount = 0; TryAction: try { Context.Pr_WorkflowInstanceRaiseException(workflowInstanceTaskID, completedByUserName, comments, errorMessage); error = errorMessage.Value.ToStringSafe(); } catch (Exception ex) { var message = GetInnermostMessage(ex); error = message; if (!String.IsNullOrEmpty(message) && message.ToLower().Contains("deadlock") && tryActionCount < 5) { Random rnd = new Random(); Thread.Sleep(rnd.Next(2000, 4000)); tryActionCount++; goto TryAction; } else { throw ex; } } return string.IsNullOrEmpty(error); } #endregion #region GetInnermostMessage public string GetInnermostMessage(Exception ex) { if (ex.InnerException == null) { return ex.Message; } else { return GetInnermostMessage(ex.InnerException); } } #endregion } }