//[TestMethod]
        public void Test_Create_Graph_Ok()
        {
            DBController  db  = DBController.Create(connectionString);
            Workflow      wf  = db.WorkflowMetadataGet("Test100");
            WorkflowGraph wfg = WorkflowGraph.Create(wf, db);

            Assert.IsTrue(wfg.WorkflowRunStatus.StatusCode == WfStatus.Unknown);
        }
Esempio n. 2
0
        public override void InitializeWorkflow(WorkflowGraph graph)
        {
            // connect event forwarder
            if (base.Workflow != null)
            {
                base.Workflow.OnStateTransition -= OG.ForwardStateTransition;
            }
            graph.OnStateTransition += OG.ForwardStateTransition;

            base.InitializeWorkflow(graph);
        }
Esempio n. 3
0
        public void OneWorkTest()
        {
            _testState = 0;

            var graph = new WorkflowGraph()
            {
                new Work(0, new IStateItem[] { new FakeStateItem(0, 0) }),
            };

            graph.RunParallel(_context);

            graph.OfType <Work>()
            .All(x => x.StateItems.OfType <FakeStateItem>().First().IsDone)
            .Should().BeTrue();
        }
        public void Test_Graph_Run_Ok()
        {
            DBController  db  = DBController.Create(connectionString);
            Workflow      wf  = db.WorkflowMetadataGet("Test100");
            WorkflowGraph wfg = WorkflowGraph.Create(wf, db);

            wfg.Start();

            BlockingCollection <string> step_set = new BlockingCollection <string>();

            Task t1 = Task.Factory.StartNew(() =>
            {
                WorkflowStep step = null;
                while (wfg.TryTake(out step, TimeSpan.FromMinutes(5)))
                {
                    wfg.SetNodeExecutionResult(step.Key, WfResult.Started);
                    Thread.Sleep(1000);
                    step_set.Add(step.Key);
                }

                step_set.CompleteAdding();
                Console.WriteLine(String.Format("Finishing Step Submitting thread"));
            });

            Task t2 = Task.Factory.StartNew(() =>
            {
                string Key = String.Empty;
                while (step_set.TryTake(out Key, -1))
                {
                    Console.WriteLine(String.Format("Processing step {0}", Key));
                    wfg.SetNodeExecutionResult(Key, WfResult.Succeeded);
                    //wfg.SetNodeExecutionResult(Key, WfResult.Failed);
                }

                Console.WriteLine(String.Format("Finishing Step Processing thread"));
            });

            Task.WaitAll(t1, t2);

            WfResult wr = wfg.WorkflowRunStatus;
            WfResult wc = wfg.WorkflowCompleteStatus;

            Console.WriteLine(String.Format("Run status {0}", wr.StatusCode.ToString()));
            Console.WriteLine(String.Format("Complete status {0}", wc.StatusCode.ToString()));
            Assert.IsTrue(wr.StatusCode == WfStatus.Succeeded);
        }
Esempio n. 5
0
        public void TwoDependencyTest()
        {
            _testState  = -1;
            _traceQueue = new ConcurrentQueue <int>();

            var graph = new WorkflowGraph()
            {
                new Work(0, new IStateItem[] { new FakeStateItem(-1, 0) }),
                new Work(1, new IStateItem[] { new FakeStateItem(0, 1) }),
                new DirectedEdge(0, 1),
            };

            graph.RunParallel(_context);

            graph.OfType <Work>()
            .All(x => x.StateItems.OfType <FakeStateItem>().First().IsDone)
            .Should().BeTrue();

            _testState.Should().Be(1);
        }
        //[TestMethod]
        public void Test_Workflow_Steps_Run_Ok()
        {
            DBController  db  = DBController.Create(connectionString);
            Workflow      wf  = db.WorkflowMetadataGet("Test100");
            WorkflowGraph wfg = WorkflowGraph.Create(wf, db);

            Task[] tasks = new Task[wfg.Count];

            WfResult wf_status = wfg.Start();

            WorkflowStep step = null;
            int          i    = 0;

            while (wfg.TryTake(out step, TimeSpan.FromMinutes(5)))
            {
                wfg.SetNodeExecutionResult(step.Key, WfResult.Started);
                tasks[i++] =
                    Task.Factory.StartNew((object obj) =>
                {
                    WorkflowStep s = obj as WorkflowStep;
                    Console.WriteLine(String.Format("Processing step {0}", s.Key));
                    Thread.Sleep(1000);
                    wfg.SetNodeExecutionResult(s.Key, WfResult.Succeeded);
                    //wfg.SetNodeExecutionResult(Key, WfResult.Failed);
                }, step);
            }

            Task.WaitAll(tasks);

            WfResult wr = wfg.WorkflowRunStatus;
            WfResult wc = wfg.WorkflowCompleteStatus;

            Console.WriteLine(String.Format("Run status {0}", wr.StatusCode.ToString()));
            Console.WriteLine(String.Format("Complete status {0}", wc.StatusCode.ToString()));
            Assert.IsTrue(wr.StatusCode == WfStatus.Succeeded);
        }
Esempio n. 7
0
        public static void Start(SchemaBuilder sb, Func <WorkflowConfigurationEmbedded> getConfiguration)
        {
            if (sb.NotDefined(MethodInfo.GetCurrentMethod()))
            {
                PermissionAuthLogic.RegisterPermissions(WorkflowPermission.ViewWorkflowPanel);
                PermissionAuthLogic.RegisterPermissions(WorkflowPermission.ViewCaseFlow);

                WorkflowLogic.getConfiguration = getConfiguration;

                sb.Include <WorkflowEntity>()
                .WithQuery(() => DynamicQueryCore.Auto(
                               from e in Database.Query <WorkflowEntity>()
                               select new
                {
                    Entity = e,
                    e.Id,
                    e.Name,
                    e.MainEntityType,
                    HasExpired = e.HasExpired(),
                    e.ExpirationDate,
                })
                           .ColumnDisplayName(a => a.HasExpired, () => WorkflowMessage.HasExpired.NiceToString()))
                .WithExpressionFrom((CaseActivityEntity ca) => ca.Workflow());

                WorkflowGraph.Register();
                QueryLogic.Expressions.Register((WorkflowEntity wf) => wf.WorkflowStartEvent());
                QueryLogic.Expressions.Register((WorkflowEntity wf) => wf.HasExpired(), () => WorkflowMessage.HasExpired.NiceToString());
                sb.AddIndex((WorkflowEntity wf) => wf.ExpirationDate);

                DynamicCode.GetCustomErrors += GetCustomErrors;


                sb.Include <WorkflowPoolEntity>()
                .WithUniqueIndex(wp => new { wp.Workflow, wp.Name })
                .WithSave(WorkflowPoolOperation.Save)
                .WithDelete(WorkflowPoolOperation.Delete)
                .WithExpressionFrom((WorkflowEntity p) => p.WorkflowPools())
                .WithQuery(() => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Name,
                    e.BpmnElementId,
                    e.Workflow,
                });

                sb.Include <WorkflowLaneEntity>()
                .WithUniqueIndex(wp => new { wp.Pool, wp.Name })
                .WithSave(WorkflowLaneOperation.Save)
                .WithDelete(WorkflowLaneOperation.Delete)
                .WithExpressionFrom((WorkflowPoolEntity p) => p.WorkflowLanes())
                .WithQuery(() => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Name,
                    e.BpmnElementId,
                    e.Pool,
                    e.Pool.Workflow,
                });

                sb.Include <WorkflowActivityEntity>()
                .WithUniqueIndex(w => new { w.Lane, w.Name })
                .WithSave(WorkflowActivityOperation.Save)
                .WithDelete(WorkflowActivityOperation.Delete)
                .WithExpressionFrom((WorkflowEntity p) => p.WorkflowActivities())
                .WithExpressionFrom((WorkflowLaneEntity p) => p.WorkflowActivities())
                .WithVirtualMList(wa => wa.BoundaryTimers, e => e.BoundaryOf, WorkflowEventOperation.Save, WorkflowEventOperation.Delete)
                .WithQuery(() => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Name,
                    e.BpmnElementId,
                    e.Comments,
                    e.Lane,
                    e.Lane.Pool.Workflow,
                });

                sb.Include <WorkflowEventEntity>()
                .WithExpressionFrom((WorkflowEntity p) => p.WorkflowEvents())
                .WithExpressionFrom((WorkflowLaneEntity p) => p.WorkflowEvents())
                .WithQuery(() => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Type,
                    e.Name,
                    e.BpmnElementId,
                    e.Lane,
                    e.Lane.Pool.Workflow,
                });


                new Graph <WorkflowEventEntity> .Execute(WorkflowEventOperation.Save)
                {
                    CanBeNew      = true,
                    CanBeModified = true,
                    Execute       = (e, _) => {
                        if (e.Timer == null && e.Type.IsTimer())
                        {
                            throw new InvalidOperationException(ValidationMessage._0IsMandatoryWhen1IsSetTo2.NiceToString(e.NicePropertyName(a => a.Timer), e.NicePropertyName(a => a.Type), e.Type.NiceToString()));
                        }

                        if (e.Timer != null && !e.Type.IsTimer())
                        {
                            throw new InvalidOperationException(ValidationMessage._0ShouldBeNullWhen1IsSetTo2.NiceToString(e.NicePropertyName(a => a.Timer), e.NicePropertyName(a => a.Type), e.Type.NiceToString()));
                        }

                        if (e.BoundaryOf == null && e.Type.IsBoundaryTimer())
                        {
                            throw new InvalidOperationException(ValidationMessage._0IsMandatoryWhen1IsSetTo2.NiceToString(e.NicePropertyName(a => a.BoundaryOf), e.NicePropertyName(a => a.Type), e.Type.NiceToString()));
                        }

                        if (e.BoundaryOf != null && !e.Type.IsBoundaryTimer())
                        {
                            throw new InvalidOperationException(ValidationMessage._0ShouldBeNullWhen1IsSetTo2.NiceToString(e.NicePropertyName(a => a.BoundaryOf), e.NicePropertyName(a => a.Type), e.Type.NiceToString()));
                        }

                        e.Save();
                    },
                }

                .Register();

                new Graph <WorkflowEventEntity> .Delete(WorkflowEventOperation.Delete)
                {
                    Delete = (e, _) =>
                    {
                        if (e.Type.IsScheduledStart())
                        {
                            var scheduled = e.ScheduledTask();
                            if (scheduled != null)
                            {
                                WorkflowEventTaskLogic.DeleteWorkflowEventScheduledTask(scheduled);
                            }
                        }

                        e.Delete();
                    },
                }

                .Register();

                sb.Include <WorkflowGatewayEntity>()
                .WithSave(WorkflowGatewayOperation.Save)
                .WithDelete(WorkflowGatewayOperation.Delete)
                .WithExpressionFrom((WorkflowEntity p) => p.WorkflowGateways())
                .WithExpressionFrom((WorkflowLaneEntity p) => p.WorkflowGateways())
                .WithQuery(() => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Type,
                    e.Name,
                    e.BpmnElementId,
                    e.Lane,
                    e.Lane.Pool.Workflow,
                });

                sb.Include <WorkflowConnectionEntity>()
                .WithSave(WorkflowConnectionOperation.Save)
                .WithDelete(WorkflowConnectionOperation.Delete)
                .WithExpressionFrom((WorkflowEntity p) => p.WorkflowConnections())
                .WithExpressionFrom((WorkflowEntity p) => p.WorkflowMessageConnections(), null !)
                .WithExpressionFrom((WorkflowPoolEntity p) => p.WorkflowConnections())
                .WithExpressionFrom((IWorkflowNodeEntity p) => p.NextConnections(), null !)
                .WithExpressionFrom((IWorkflowNodeEntity p) => p.PreviousConnections(), null !)
                .WithQuery(() => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Name,
                    e.BpmnElementId,
                    e.From,
                    e.To,
                });

                WorkflowEventTaskEntity.GetWorkflowEntity = lite => WorkflowGraphLazy.Value.GetOrThrow(lite).Workflow;

                WorkflowGraphLazy = sb.GlobalLazy(() =>
                {
                    using (new EntityCache())
                    {
                        var events      = Database.RetrieveAll <WorkflowEventEntity>().GroupToDictionary(a => a.Lane.Pool.Workflow.ToLite());
                        var gateways    = Database.RetrieveAll <WorkflowGatewayEntity>().GroupToDictionary(a => a.Lane.Pool.Workflow.ToLite());
                        var activities  = Database.RetrieveAll <WorkflowActivityEntity>().GroupToDictionary(a => a.Lane.Pool.Workflow.ToLite());
                        var connections = Database.RetrieveAll <WorkflowConnectionEntity>().GroupToDictionary(a => a.From.Lane.Pool.Workflow.ToLite());

                        var result = Database.RetrieveAll <WorkflowEntity>().ToDictionary(workflow => workflow.ToLite(), workflow =>
                        {
                            var w         = workflow.ToLite();
                            var nodeGraph = new WorkflowNodeGraph
                            {
                                Workflow    = workflow,
                                Events      = events.TryGetC(w).EmptyIfNull().ToDictionary(e => e.ToLite()),
                                Gateways    = gateways.TryGetC(w).EmptyIfNull().ToDictionary(g => g.ToLite()),
                                Activities  = activities.TryGetC(w).EmptyIfNull().ToDictionary(a => a.ToLite()),
                                Connections = connections.TryGetC(w).EmptyIfNull().ToDictionary(c => c.ToLite()),
                            };

                            nodeGraph.FillGraphs();
                            return(nodeGraph);
                        });

                        return(result);
                    }
                }, new InvalidateWith(typeof(WorkflowConnectionEntity)));
                WorkflowGraphLazy.OnReset += (e, args) => DynamicCode.OnInvalidated?.Invoke();

                Validator.PropertyValidator((WorkflowConnectionEntity c) => c.Condition).StaticPropertyValidation = (e, pi) =>
                {
                    if (e.Condition != null && e.From != null)
                    {
                        var conditionType = Conditions.Value.GetOrThrow(e.Condition).MainEntityType;
                        var workflowType  = e.From.Lane.Pool.Workflow.MainEntityType;

                        if (!conditionType.Is(workflowType))
                        {
                            return(WorkflowMessage.Condition0IsDefinedFor1Not2.NiceToString(conditionType, workflowType));
                        }
                    }

                    return(null);
                };

                StartWorkflowConditions(sb);

                StartWorkflowTimerConditions(sb);

                StartWorkflowActions(sb);

                StartWorkflowScript(sb);
            }
        }
Esempio n. 8
0
        public void NoWorkTest()
        {
            var graph = new WorkflowGraph();

            graph.RunParallel(_context);
        }
Esempio n. 9
0
        public static void Start(SchemaBuilder sb, DynamicQueryManager dqm, Func <WorkflowConfigurationEmbedded> getConfiguration)
        {
            if (sb.NotDefined(MethodInfo.GetCurrentMethod()))
            {
                PermissionAuthLogic.RegisterPermissions(WorkflowScriptRunnerPanelPermission.ViewWorkflowScriptRunnerPanel);

                WorkflowLogic.getConfiguration = getConfiguration;

                sb.Include <WorkflowEntity>()
                .WithQuery(dqm, () => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Name,
                    e.MainEntityType,
                    e.MainEntityStrategy,
                });

                WorkflowGraph.Register();
                dqm.RegisterExpression((WorkflowEntity wf) => wf.WorkflowStartEvent());

                DynamicCode.GetCustomErrors += GetCustomErrors;


                sb.Include <WorkflowPoolEntity>()
                .WithUniqueIndex(wp => new { wp.Workflow, wp.Name })
                .WithSave(WorkflowPoolOperation.Save)
                .WithDelete(WorkflowPoolOperation.Delete)
                .WithExpressionFrom(dqm, (WorkflowEntity p) => p.WorkflowPools())
                .WithQuery(dqm, () => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Name,
                    e.BpmnElementId,
                    e.Workflow,
                });

                sb.Include <WorkflowLaneEntity>()
                .WithUniqueIndex(wp => new { wp.Pool, wp.Name })
                .WithSave(WorkflowLaneOperation.Save)
                .WithDelete(WorkflowLaneOperation.Delete)
                .WithExpressionFrom(dqm, (WorkflowPoolEntity p) => p.WorkflowLanes())
                .WithQuery(dqm, () => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Name,
                    e.BpmnElementId,
                    e.Pool,
                    e.Pool.Workflow,
                });

                sb.Include <WorkflowActivityEntity>()
                .WithUniqueIndex(w => new { w.Lane, w.Name })
                .WithSave(WorkflowActivityOperation.Save)
                .WithDelete(WorkflowActivityOperation.Delete)
                .WithExpressionFrom(dqm, (WorkflowEntity p) => p.WorkflowActivities())
                .WithExpressionFrom(dqm, (WorkflowLaneEntity p) => p.WorkflowActivities())
                .WithQuery(dqm, () => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Name,
                    e.BpmnElementId,
                    e.Comments,
                    e.Lane,
                    e.Lane.Pool.Workflow,
                });

                sb.AddUniqueIndexMList((WorkflowActivityEntity a) => a.Jumps, mle => new { mle.Parent, mle.Element.To });

                sb.Include <WorkflowEventEntity>()
                .WithSave(WorkflowEventOperation.Save)
                .WithExpressionFrom(dqm, (WorkflowEntity p) => p.WorkflowEvents())
                .WithExpressionFrom(dqm, (WorkflowLaneEntity p) => p.WorkflowEvents())
                .WithQuery(dqm, () => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Type,
                    e.Name,
                    e.BpmnElementId,
                    e.Lane,
                    e.Lane.Pool.Workflow,
                });

                new Graph <WorkflowEventEntity> .Delete(WorkflowEventOperation.Delete)
                {
                    Delete = (e, _) =>
                    {
                        if (e.Type.IsTimerStart())
                        {
                            var scheduled = e.ScheduledTask();
                            if (scheduled != null)
                            {
                                WorkflowEventTaskLogic.DeleteWorkflowEventScheduledTask(scheduled);
                            }
                        }

                        e.Delete();
                    },
                }

                .Register();

                sb.Include <WorkflowGatewayEntity>()
                .WithSave(WorkflowGatewayOperation.Save)
                .WithDelete(WorkflowGatewayOperation.Delete)
                .WithExpressionFrom(dqm, (WorkflowEntity p) => p.WorkflowGateways())
                .WithExpressionFrom(dqm, (WorkflowLaneEntity p) => p.WorkflowGateways())
                .WithQuery(dqm, () => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Type,
                    e.Name,
                    e.BpmnElementId,
                    e.Lane,
                    e.Lane.Pool.Workflow,
                });

                sb.Include <WorkflowConnectionEntity>()
                .WithSave(WorkflowConnectionOperation.Save)
                .WithDelete(WorkflowConnectionOperation.Delete)
                .WithExpressionFrom(dqm, (WorkflowEntity p) => p.WorkflowConnections())
                .WithExpressionFrom(dqm, (WorkflowEntity p) => p.WorkflowMessageConnections(), null)
                .WithExpressionFrom(dqm, (WorkflowPoolEntity p) => p.WorkflowConnections())
                .WithExpressionFrom(dqm, (IWorkflowNodeEntity p) => p.NextConnections(), null)
                .WithExpressionFrom(dqm, (IWorkflowNodeEntity p) => p.PreviousConnections(), null)
                .WithQuery(dqm, () => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Name,
                    e.BpmnElementId,
                    e.From,
                    e.To,
                });

                WorkflowGraphLazy = sb.GlobalLazy(() =>
                {
                    using (new EntityCache())
                    {
                        var events      = Database.RetrieveAll <WorkflowEventEntity>().GroupToDictionary(a => a.Lane.Pool.Workflow.ToLite());
                        var gateways    = Database.RetrieveAll <WorkflowGatewayEntity>().GroupToDictionary(a => a.Lane.Pool.Workflow.ToLite());
                        var activities  = Database.RetrieveAll <WorkflowActivityEntity>().GroupToDictionary(a => a.Lane.Pool.Workflow.ToLite());
                        var connections = Database.RetrieveAll <WorkflowConnectionEntity>().GroupToDictionary(a => a.From.Lane.Pool.Workflow.ToLite());

                        var result = Database.RetrieveAll <WorkflowEntity>().ToDictionary(workflow => workflow.ToLite(), workflow =>
                        {
                            var w         = workflow.ToLite();
                            var nodeGraph = new WorkflowNodeGraph
                            {
                                Workflow    = workflow,
                                Events      = events.TryGetC(w).EmptyIfNull().ToDictionary(e => e.ToLite()),
                                Gateways    = gateways.TryGetC(w).EmptyIfNull().ToDictionary(g => g.ToLite()),
                                Activities  = activities.TryGetC(w).EmptyIfNull().ToDictionary(a => a.ToLite()),
                                Connections = connections.TryGetC(w).EmptyIfNull().ToDictionary(c => c.ToLite()),
                            };

                            nodeGraph.FillGraphs();
                            return(nodeGraph);
                        });

                        return(result);
                    }
                }, new InvalidateWith(typeof(WorkflowConnectionEntity)));

                Validator.PropertyValidator((WorkflowConnectionEntity c) => c.Condition).StaticPropertyValidation = (e, pi) =>
                {
                    if (e.Condition != null && e.From != null)
                    {
                        var conditionType = Conditions.Value.GetOrThrow(e.Condition).MainEntityType;
                        var workflowType  = e.From.Lane.Pool.Workflow.MainEntityType;

                        if (!conditionType.Is(workflowType))
                        {
                            return(WorkflowMessage.Condition0IsDefinedFor1Not2.NiceToString(conditionType, workflowType));
                        }
                    }

                    return(null);
                };

                sb.Include <WorkflowConditionEntity>()
                .WithSave(WorkflowConditionOperation.Save)
                .WithQuery(dqm, () => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Name,
                    e.MainEntityType,
                    e.Eval.Script
                });

                new Graph <WorkflowConditionEntity> .Delete(WorkflowConditionOperation.Delete)
                {
                    Delete = (e, _) =>
                    {
                        ThrowConnectionError(Database.Query <WorkflowConnectionEntity>().Where(a => a.Condition == e.ToLite()), e);
                        e.Delete();
                    },
                }

                .Register();

                new Graph <WorkflowConditionEntity> .ConstructFrom <WorkflowConditionEntity>(WorkflowConditionOperation.Clone)
                {
                    Construct = (e, args) =>
                    {
                        return(new WorkflowConditionEntity
                        {
                            MainEntityType = e.MainEntityType,
                            Eval = new WorkflowConditionEval {
                                Script = e.Eval.Script
                            }
                        });
                    },
                }

                .Register();

                WorkflowEventTaskEntity.GetWorkflowEntity = lite => WorkflowGraphLazy.Value.GetOrThrow(lite).Workflow;

                Conditions = sb.GlobalLazy(() => Database.Query <WorkflowConditionEntity>().ToDictionary(a => a.ToLite()),
                                           new InvalidateWith(typeof(WorkflowConditionEntity)));

                sb.Include <WorkflowActionEntity>()
                .WithSave(WorkflowActionOperation.Save)
                .WithQuery(dqm, () => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Name,
                    e.MainEntityType,
                    e.Eval.Script
                });

                new Graph <WorkflowActionEntity> .Delete(WorkflowActionOperation.Delete)
                {
                    Delete = (e, _) =>
                    {
                        ThrowConnectionError(Database.Query <WorkflowConnectionEntity>().Where(a => a.Action == e.ToLite()), e);
                        e.Delete();
                    },
                }

                .Register();

                new Graph <WorkflowActionEntity> .ConstructFrom <WorkflowActionEntity>(WorkflowActionOperation.Clone)
                {
                    Construct = (e, args) =>
                    {
                        return(new WorkflowActionEntity
                        {
                            MainEntityType = e.MainEntityType,
                            Eval = new WorkflowActionEval {
                                Script = e.Eval.Script
                            }
                        });
                    },
                }

                .Register();

                Actions = sb.GlobalLazy(() => Database.Query <WorkflowActionEntity>().ToDictionary(a => a.ToLite()),
                                        new InvalidateWith(typeof(WorkflowActionEntity)));

                sb.Include <WorkflowScriptEntity>()
                .WithSave(WorkflowScriptOperation.Save)
                .WithQuery(dqm, () => s => new
                {
                    Entity = s,
                    s.Id,
                    s.Name,
                    s.MainEntityType,
                });

                new Graph <WorkflowScriptEntity> .Delete(WorkflowScriptOperation.Delete)
                {
                    Delete = (s, _) =>
                    {
                        ThrowConnectionError(Database.Query <WorkflowActivityEntity>().Where(a => a.Script.Script == s.ToLite()), s);
                        s.Delete();
                    },
                }

                .Register();

                Scripts = sb.GlobalLazy(() => Database.Query <WorkflowScriptEntity>().ToDictionary(a => a.ToLite()),
                                        new InvalidateWith(typeof(WorkflowScriptEntity)));

                sb.Include <WorkflowScriptRetryStrategyEntity>()
                .WithSave(WorkflowScriptRetryStrategyOperation.Save)
                .WithDelete(WorkflowScriptRetryStrategyOperation.Delete)
                .WithQuery(dqm, () => e => new
                {
                    Entity = e,
                    e.Id,
                    e.Rule
                });
            }
        }