2

我想知道人们如何处理以下情况(这是假设的想法)......

  • TABLE A (Orders): OrderId, StatusId等(状态表上的外键)
  • TABLE B (Statuses): StatusId, Name,ETC

表 B 需要存在(IOW,例如,我不能只创建一个状态枚举),因为订单状态列表需要随着业务需求和实践的变化而动态变化,并且您的程序中有方法,如GetAllOrders(), GetAllStatuses(),GetOrderByStatus(int statusId)等。但是,您似乎一直需要访问“硬编码”状态。例如,当第一次创建订单时,它的状态是“新建”,您需要在没有任何用户干预的情况下将其设置为该状态。也许您有一个 GetUnfilledOrders 报告,它返回所有正在“处理”的订单,同样无需用户选择他们正在寻找的状态,因为报告的名称暗示了他们想要的东西。我希望你能明白。

在这些情况下,我一直在做的是创建一个设置,例如DefaultNewOrderStatus (int)并将其设置为我想用于新订单的状态的 id,或者StatusesForUnfilledOrdersReport (int[])再次设置要使用的状态列表。如果我们的状态“架构”发生变化,我可以即时更改这些设置。问题是需要使用的“硬编码”值的数量似乎在增加(也许现在我需要一个默认状态来设置已完成的订单,或者一个状态列表用于显示“打开”订单 UI 视图,等)以及随之而来的,处理它们的设置数量也是如此。

我非常想知道其他人如何处理这些情况?

4

4 回答 4

1

我不确定我是否抓住了您的问题的重点,但看起来您正在尝试以“硬编码”方式实施业务流程管理器。你真正需要的不是动态的状态列表,而是动态的进程列表,实际上是如何使用状态的场景。此外,您需要操作,这将触发状态更改。因此,例如,您有一个状态列表:

  1. 新的
  2. 加工
  3. 送货
  4. 完成的

接下来是动作列表:

  1. 创建新的
  2. 开始加工
  3. 进入交货
  4. 完成交货
  5. 回来

现在,您可以设计一个流程:

  • [开始] ->(创建新)-> 新
  • 新 -> (开始处理)-> 处理
  • 处理 -> (进入交付) -> 交付
  • 交付 ->(退回)-> 处理
  • 交付->(完成交付)->完成

您的应用程序需要有一组可以对上述内容进行操作的方法(通常是表单、一些向导等)。当某些事情发生变化时,您添加新的状态,复制和修改流程并且您的应用程序已经知道如何处理它,例如您需要处理取消订单。您将取消添加到您的操作,取消添加到您的订单并创建新流程(或修改旧流程)添加:

  • 处理中->(取消)->已取消

所以,总而言之,你的问题不仅仅是状态变化,而是业务流程的变化。在这种情况下,您需要拥有动态流程,而不仅仅是状态。比,问题消失了——但你需要重建你的应用程序——或者更确切地说是构建一个新的应用程序。

编辑

关于报道,情况完全不同。如果您找到一种方法来准备能够生成任何报告的通用架构,那么您将挑战商业智能的实际形​​式、数据仓库概念等。:-)

于 2012-09-17T19:22:19.990 回答
0

我喜欢@WojtusJ 的回答,反正还有另一种选择:

您可以创建一个状态设置页面,您可以在其中设置具体statusId的状态情况,所以它看起来像这样:

New status:         [Select a status]
Received status:    [Select a status]
Processing status:  [Select a status]
Complete status:    [Select a status]

并且您将通过一个键存储这些设置,例如'new','received'等。然后您可以获得新订单statusId'new'状态并继续 -'new' statusId与 name 的状态无关Completed

于 2012-09-24T08:55:18.873 回答
0

这就是我的处理方式。常见的场景是 int, string 以 int 为 key。将流体列表读入 ctor 中的字典。所以我定义了流体,因为他们需要重新启动应用程序才能获得一个新的列表。

    public static Dictionary<int, string> FluidStatus { get; private set; }  // poulate in ctor
    public class FluidBus
    {
        public Int32 ID { get; set; }  // in set need error checking the ID is in range
        public String Status { get { return FluidStatus[ID]; } }  // need to check the ID is in range
        public FluidBus() { ID = 0; } // default
        public FluidBus(Int32 id) { ID = id; }
        // alternative is to pass a reference to Dictionary in the ctor as then  
        // can change out the status without changing the class
    }

实际上,我主要将它与 SysName 和 DispName 一起使用,规则 SysName 不能有空格。DispName 是用户看到的内容。但是对于类似 XML 的导出,我使用 SysName。这样管理员就可以处理用户的突发奇想并为他们保留一些半静态的名称。

如果它是程序需要使用的状态,那么每次都使用 Enum。在 SQL 方面,我将有一个 C# 不使用的 FK 表,但作为一个公共约束,当我在 SQL 中时,我可以查找名称。

于 2012-09-17T19:25:04.417 回答
0

制作枚举。此枚举适用于您的业务逻辑。您仍然可以从数据库查询中显示可用状态列表。

当您将 StatusId 转换为 StatusEnum 值时,您需要在数据库中有一个新值的案例。但是,您的所有逻辑都应该没问题,因为 New 仍然是 New。如果您需要编写使用新创建状态的逻辑,请更新 Enum。

对于状态之类的东西,没有理由在现有行上更改 StatusId。如果删除了行,则您的 Enum 很好,该值将永远不会被使用。您可以在进行其他维护时将其移除。

于 2012-09-17T18:56:06.093 回答