2012-09-17 60 views
2

我想知道人們是如何處理以下情形(這是假設跨越的想法)...最佳實踐檢索「硬」值從關係數據庫

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

表B必須存在(IOW,我不能只是創建狀態例如枚舉),因爲訂單狀態列表需要是動態的業務需求和習慣改變,你在y中有方法我們的程序如GetAllOrders()GetAllStatuses(),GetOrderByStatus(int statusId)等。但是,似乎您不斷需要訪問「硬編碼」狀態。例如,首次創建訂單時,狀態爲「新建」,您需要將其設置爲該狀態,無需用戶干預。也許你有一個GetUnfilledOrders報告,它可以返回所有正在「處理」的訂單,而不需要用戶選擇他們正在查找的狀態,因爲報告的名稱意味着他們想要的。我希望你明白這個主意。

我在這些情況下一直在做的是創建一個設置,如DefaultNewOrderStatus (int)並將其設置爲我想用於新訂單的狀態的編號或StatusesForUnfilledOrdersReport (int[])並再次設置要使用的狀態列表。我的想法是,如果我們的狀態「體系結構」發生變化,我可以即時更改這些設置。問題是需要使用的「硬編碼」值的數量似乎增加(也許現在我需要一個默認狀態來設置已完成的訂單,或用於顯示「打開」訂單UI視圖的狀態列表,等等)以及它一起,處理它們的設置數量也是如此。

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

+0

首先硬編碼狀態值(作爲枚舉)有什麼問題? – usr

+0

在這種假想的情況下,正如我所指出的,訂單「狀態」需要是「流動的」,以便隨着業務實踐或需求的變化可以對其進行修改。 (也許有人認爲「新訂單」確實應該是「最近收到的」,或者我們需要添加「延期交貨」狀態)。使用硬編碼的枚舉,每次需要更改時都必須重新編譯和部署該程序。 –

+0

@ScottHarris「Hard Values」的標題與「Fluid」相反 – Paparazzi

回答

0

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

當您將StatusId轉換爲StatusEnum值時,您需要在數據庫中有一個新值的情況。然而,你的所有邏輯都應該沒問題,因爲New仍然是New。如果您需要編寫使用新創建狀態的邏輯,請更新Enum。

對於像狀態這樣的東西,StatusId應該在現有的行上改變。如果行被刪除,你的Enum就很好,那個值永遠不會被使用。您在進行其他維護時可以將其刪除。

1

我不確定是否抓住了您的問題,但看起來您嘗試以「硬編碼」方式實施業務流程管理器。你實際需要的不是一個動態的狀態列表,而是動態的過程列表,事實上它們是如何使用狀態的場景。另外你需要動作,這會觸發狀態的改變。所以,讓我們舉個例子,你有狀態的列表:成品

下,操作列表

  1. 處理
  2. 交付
    1. 創建新
    2. 開始處理
    3. 進入DELIVERY
    4. FINISH DELIVERY
    5. RETURNED現在

    ,可以設計的方法:

    • [START] - >(新建) - > NEW
    • 新 - >(開始處理) - >處理
    • 處理 - >(進入交付) - >交付
    • DELIVERY - >(返回) - >加工
    • DELIVERY - >(FINISH DELIVERY) - > FINISHED

    你的應用需要有一組可在上述(形式通常操作的方法,一些嚮導等)。當某些事情發生變化時,您會添加新的狀態,複製和修改流程,並且您的應用程序已經知道如何處理它,例如您需要處理取消訂單的事宜。您添加取消對你的行動,取消了訂單,並創建新的進程(或修改舊的)補充說:

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

    所以,綜上所述,您的問題不僅僅是狀態改變,而是業務流程的變化。在這種情況下,您需要擁有動態的流程,而不僅僅是狀態。比問題消失 - 但你需要重建你的應用程序 - 或者建立一個新的應用程序。

    編輯

    關於報告,這是一個完全不同的局面。如果您找到一種方法來準備能夠生成任何報告的通用架構,那麼您將面臨挑戰商業智能,數據倉庫概念等實際形式的挑戰。:-)

+0

這看起來正是我所追求的。你是對的,我一直在想它完全錯誤! 現在,我從來沒有實施過這樣的事情。你把你的「動作」存儲在數據庫中,並將它們以某種方式映射到應用程序中?與您的流程一樣,您是否將它們存儲在數據庫中並將它們映射到您的應用程序中?你有沒有鏈接到我可以閱讀的任何引用來更好地理解如何實現這樣的東西? –

+0

這實際上並不是一件容易的事情,但可以應用於許多不同的業務 - 就像通常的解決方案一樣。有很多不同的工具,他們叫做BPM(業務流程管理器),你可以谷歌的一些例子,甚至看看它是如何工作的。我曾與其中之一合作過,它被稱爲Metastorm(我猜,現在OpenText)。回到你的問題,它是如何實現是一個特殊情況的真正metter,因爲我說更通用,通常更好,但也更復雜和更難以開發和維護。 – WojtusJ

0

這就是我如何處理它。常見的情況是int,字符串以int作爲鍵。將流體列表讀入ctor中的Dictionary。所以我定義了流體,因爲他們需要重新啓動應用程序才能獲得新清單。

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中時,我可以查找該名稱。

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',等等,那麼你可以得到的'new'狀態statusId新秩序,並繼續 - 不要緊,'new'statusId reffers與域名狀態Completed