StateMachine在主 - 详细模型中流动

时间:2011-09-20 15:21:09

标签: c# oracle database-design devexpress xaf

我需要问一个复杂的场景,所以我会试着通过例子来解释。

考虑以下模型:

public enum States { Created, Approved, Started, Completed }

public class Request {
    States State {get; set;}
    IEnumerable<RequestLine> Lines {get; set;}
}

public class RequestLine {
    States State {get; set;}
    Request Request {get; set;}
    IEnumerable<WorkOrder> WorkOrders {get; set;}
}   

public class WorkOrder {
    States State {get; set;}
    RequestLine RequestLine {get; set;}
    IEnumerable<WorkOrderAction> Actions {get; set;}
}

public class WorkOrderAction {
    States State {get; set;}
    WorkOrder WorkOrder {get; set;}
}

所以每个唱片都有一个状态,并且它们都是连接的。创建WorkOrderAction时,我必须更新WorkOrder状态,然后更新RequesTLine状态,然后更新Request状态。对于每个WorkOrderAction记录,我应检查其他子记录State并更新父记录。

我可以使用数据库触发器执行此操作,我不喜欢这样做。我在应用程序级别使用Devexpress XAF,所以我也可以编写一些逻辑。但我还是无法确定哪种方法更好。

链接状态机有一个共同的概念吗?

3 个答案:

答案 0 :(得分:2)

我们只需要知道“其他未完成的孩子”。

  1. 我们可以枚举所有这些:foreach(parent.Children)if(child.State!= Completed)。但是这样会加载它们所以会有性能损失
  2. 我们可以使用Execute(new BinaryOperator(“State”,Completed,NotEquals),AggreagateOperand.Count)执行到数据库的往返。这需要对域进行重组,并且性能损失小于前一个。
  3. 我们可以在保存/删除/删除/添加每个孩子时更新父母的'IncompletedChildren'成员(整数)。始终加载父对象,以便我们可以在“IncompletedChildren == 0”时确定父对象已完成,将其标记为已完成并递归强制完成其父对象。流量没有额外的加载(一个'整数'不是“加载”imho)。 然而,这种方法强制每个'IncompletedChildren'更新的“OptimisticLoading”增量 - 它使得这种方法在某些情况下无法使用。
  4. 我会推荐第二种方法。

    PS:在我们的项目/任务系统中,我们引入了带有表达式“Items [State&lt;&gt; Completed] .Count。的计算字段。但这实际上无法工作。大多数时候至少在我们的系统中完成状态并不意味着一切都已完成:)

答案 1 :(得分:0)

通常的做法与州机器没有任何关系。也就是说,在执行数据完整性规则时,状态机并不特殊。

如果它必须适用于所有用户,那么在触发器中实现它是有意义的。只有dbms控制的代码才能为所有用户强制执行数据完整性规则。 (所有用户包括睡眠不足的DBA及其命令行工具。)

答案 2 :(得分:0)

我不完全确定我理解这个问题,但如果您要求强制执行数据完整性“级联”(级联更新),那么我会考虑设置“可延迟”约束,这将推迟检查约束检查,直到提交已发布。然后根据需要对父/子进行更新,然后提交。

以下是有关Oracle deferrable constraints的链接。