5

我的模型必须处于以下互斥状态之一:NewIn ProgressClosed

该应用程序允许用户保存记录,然后通过提供匹配状态列表来检索它们。

我继承了一个 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
}

问题是记录的模型必须具有代表单个状态的属性。

问题是,这个记录的模型的 State 属性应该是什么类型:

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 的缺点是语义:States 枚举表示状态的组合,而不是单个状态。

#2 的缺点是实用的:在存储状态时,我必须确定要存储的基础值。

你能想出一种方法来代表所有这些,同时尽量减少这些缺点吗?

4

2 回答 2

4

我会将其保留为单个非标志枚举。

当您将它传递给您的过程时,您可以使用按位或 (|) 从枚举构建整数,或者甚至只是添加值(强制转换为 int)。我会尽量避免“破坏”您的逻辑以使单个遗留查询工作,而是重新编写调用查询的代码以处理那里的异常要求。

这使代码到处都是干净的。在您的情况下,“状态”不应该是标志枚举 - 只有一种可能的状态。

于 2010-10-12T19:36:15.543 回答
1

我会选择选项 #2,然后修改您的 Get/Set 语句以确定每次的基础值。这样,每次调用属性时都会为您完成。编码一次,你就完成了。

于 2010-10-12T19:35:40.830 回答