2010-10-12 103 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语句以确定每次的基础值。每当你打电话给物业时,这样做都是为你完成的。编码一次,你就完成了。