簡體   English   中英

從關系數據庫中檢索“硬”值的最佳實踐

[英]Best Practices Retrieving “Hard” Values From Relational Database

我想知道人們如何處理以下情況(這是使想法傳播的假設)...

  • TABLE A (Orders): OrderId, StatusId等(狀態表上的外鍵)
  • TABLE B (Statuses): StatusId, Name,

表B需要存在(IOW,我不能僅創建一個狀態枚舉),因為隨着業務需求和實踐的變化,訂單狀態列表必須是動態的,並且程序中有諸如GetAllOrders()GetAllStatuses()GetOrderByStatus(int statusId)等。但是,似乎您不斷需要訪問“硬編碼”狀態。 例如,第一次創建訂單時,其狀態為“新建”,您需要在沒有任何用戶干預的情況下將其設置為該狀態。 也許您有一個GetUnfilledOrders報表,該報表返回所有“正在處理”的訂單,而又沒有讓用戶選擇他們要查找的狀態,因為報表的名稱暗示了他們想要的。 希望您能明白。

在這些情況下,我一直在做的事情是創建一個諸如DefaultNewOrderStatus (int)設置,並將其設置為我想用於新訂單的狀態的ID,或者將其設置為StatusesForUnfilledOrdersReport (int[])然后再次設置一個列表使用的狀態。 我的想法是,如果我們的狀態“體系結構”發生更改,我可以即時更改這些設置。 問題在於,需要使用的“硬編碼”值的數量似乎正在增加(也許現在我需要使用默認狀態來設置已履行的訂單,或者需要使用狀態列表來顯示“未結”訂單UI視圖,等等),以及要處理這些設置的數量。

我非常想知道其他人如何處理這些情況?

我不確定是否抓住了您的問題,但是您似乎正在嘗試以“硬編碼”方式實現Business Process Manager。 您實際需要的不是狀態的動態列表,而是過程的動態列表,實際上是有關如何使用狀態的方案。 此外,您還需要采取措施來觸發狀態更改。 因此,舉個例子,您有一個狀態列表:

  1. 處理
  2. 交貨
  3. FINISHED

接下來,列出動作:

  1. 創建新的
  2. 開始處理
  3. 送貨上門
  4. 完成交貨
  5. 回來

現在,您可以設計一個流程:

  • [開始]->(創建新內容)->新
  • 新建->(開始處理)->處理
  • 處理->(進入交貨)->交貨
  • 交付->(返回)->處理
  • 交付->(完成交付)->完成

您的應用程序需要具有一組可以對上述方法進行操作的方法(通常是窗體,某些向導等)。 發生變化時,您可以添加新狀態,復制和修改流程,並且您的應用程序已經知道如何處理該流程,例如,您需要處理訂單的取消。 您將“取消”添加到您的操作中,將“取消”添加到您的訂單中並創建新流程(或修改舊流程)並添加:

  • 處理->(取消)->取消

因此,總而言之,您的問題不只是狀態更改,而是業務流程中的更改。 在這種情況下,您不僅需要狀態,還需要動態過程。 然后,問題消失了-但是您需要重新構建應用程序-或更確切地說是構建新的應用程序。

編輯

關於報告,情況截然不同。 如果您找到一種能夠生成任何報告的通用體系結構的方法,那么您將面臨挑戰商業智能,數據倉庫概念等的實際形式:-)

進行枚舉。 該枚舉用於您的業務邏輯。 您仍然可以從數據庫查詢中顯示可用狀態列表。

當您將StatusId轉換為StatusEnum值時,將需要為數據庫中的新值指定大小寫。 但是,您的所有邏輯都應該沒問題,因為“新建”仍然是“新建”。 如果您需要編寫使用新創建狀態的邏輯,請更新Enum。

對於類似狀態的情況,沒有理由在現有行上更改StatusId。 如果刪除了行,則枚舉就可以了,該值將永遠不會被使用。 您可以在進行其他維護時將其刪除。

這就是我的處理方式。 常見的情況是int,以int為鍵的字符串。 將流體列表讀入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方面,我將有一個FK表,C#不會使用它,但它是一個常見的約束,當我使用SQL時,我可以查找名稱。

我喜歡@WojtusJ答案,無論如何,還有另一個選擇:

您可以創建一個狀態設置頁面,在其中可以為狀態情況設置一個具體的statusId ,因此如下所示:

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

然后,您將通過密鑰存儲這些設置,例如'new''received'等。然后您可以獲取新訂單的'new'狀態的statusId並繼續-無關緊要'new' statusId轉換為status名稱為Completed

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM