2010-10-12 155 views
4

我有一個模型,它必須是在以下互斥的狀態之一:正在進行,或關閉標誌枚舉和相互排斥枚舉重疊的意思

該應用程序允許用戶保存記錄,然後通過提供匹配狀態列表來檢索它們。

我繼承了一個SQL數據庫,其狀態存儲爲表示按位標誌的整數。我必須調用一個按位操作進行匹配的程序:

CREATE PROCEDURE SearchByState 
    @MatchingStates  int 
AS 
BEGIN 
    SELECT Id, State 
    FROM Records 
    WHERE @MatchingStates & State > 0 
END; 
GO 

這對我來說都很好。現在

,在C#實現,這是很清楚,我應該定義標誌來代表查詢匹配的狀態的組合:

[Flags] 
public enum States 
{ 
    None = 0x0, 
    New= 0x1, 
    InProgress = 0x2, 
    Closed = 0x4, 
    All = New | InProgress | Closed 
} 

的問題是,記錄的模式必須有一個屬性代表一個國家。

的問題是,什麼應該是這一紀錄的模型的狀態屬性的類型:

1)只要使用枚舉標誌:

public class Record 
{ 
    public int Id { get; set; } 

    // Must ensure the value is equal to one of 
    // States.New, States.InProgress, or States.Closed 
    public States State { get; set; } 
} 

2)定義新的枚舉類型用於互斥的狀態:

public enum State 
{ 
    New, 
    InProgress, 
    Closed 
} 

public class Record 
{ 
    public int Id { get; set; } 

    // Must be stored as the value of one of 
    // States.New, States.InProgress, or States.Closed 
    public State State { get; set; } 
} 

#1的缺點是語義:各國枚舉表示狀態的組合,而不是一個單一的狀態。

#2的缺點是實用的:當存儲狀態時,我必須確定要存儲的基礎值。

你能想出一種方法來表示所有這些,同時最小化這些缺點嗎?

回答

4

我將它作爲單個非標誌枚舉。

當您將此傳遞給您的過程時,您可以通過使用按位或(|)來構建枚舉中的整數,或者甚至只是將值添加(轉換爲int)。我會盡量避免「打破」你的邏輯,以便使一個傳統查詢工作,而是重新調用查詢的代碼來處理那裏的不尋常需求。

這使代碼在任何地方都保持乾淨。在你的情況下,「國家」不應該是一個國旗枚舉 - 只有一個可能的狀態。

+0

還要注意,如果OP需要執行此操作,OP將需要在其setter中進行額外驗證 - 而不是使用自動屬性。用這個問題的示例代碼,沒有什麼能夠阻止我做類似'myRecord.State =(State)123456;' – LukeH 2010-10-12 23:25:07

+0

@LukeH:True的事情,但是對於任何枚舉類型,不論是否枚舉枚舉都是如此。 – 2010-10-12 23:26:02

1

我會選擇#2,然後修改您的Get/Set語句以確定每次的基礎值。每當你打電話給物業時,這樣做都是爲你完成的。編碼一次,你就完成了。