从数据库加载枚举

时间:2010-04-05 10:39:55

标签: .net

我将.NET枚举映射到数据库表时遇到问题。想象一下,我有一个名为Statuses的表,其中包含以下值:

StatusID |名称


1草案

2准备

...

...

在应用程序层中,我可以使用Repository将所有状态作为IList对象获取。但是,这种方法的问题在于我无法在业务逻辑中引用某个状态。例如,我该如何实现这样的东西?

if (myObject.Status is Ready)
    do this
else if (myObject.Status is Draft)
    do that...

由于状态是动态加载的,我无法确定List中的哪个特定Status对象代表Draft或Ready状态。

或者,我可以使用类似

的枚举
public enum Statuses
{
    Draft, 
    Ready
};

然后我可以轻松地在我的业务逻辑中使用枚举。

if (myObject.Status == Statuses.Draft)
    // do something...

但是,这种方法的问题在于,每次用户想要修改状态列表(添加新状态或重命名现有状态)时,都必须重新编译应用程序。我们无法从数据库动态加载状态。

还有其他人遇到类似的情况吗?任何解决方案/模式?

干杯,

MOSH

2 个答案:

答案 0 :(得分:1)

执行此操作的常用方法是将您的枚举指定在可由任何其他程序集引用的公共低级程序集中(我曾经处理过的每个项目都有某种Framework或Common程序集)。

在枚举的定义中,您可以指定实际值:

public enum Status 
{
    None = 0,
    Draft = 1,
    Ready = 2
    ... etc ...
}

如果添加了状态值,请不要担心需要重新编译。如果实际上将使用该状态值,那么您无论如何都必须添加新代码(如果您的代码永远不会根据它进行决策,为什么还要关注新的状态值?)。所以在你的代码中你会有这样的东西:

if (myObject.Status == Status.MyNewValue)
    ... carry out some action ...

并且需要重新编译包含此代码的程序集,以及定义枚举的公共程序集(以便可以从此代码所在的程序集中看到新值)。数据库人员可以根据需要创建任意数量的Status值,如果您没有专门使用它们,则无需重新编译。当然,此规则也有例外 - 因为Enum默认为int,您可以从数据库中读取任何状态值并将其分配给Status属性,但如果未明确定义,则序列化将失败枚举定义中的状态枚举值。

所以简而言之:不要担心重新编译方面,只需这样做 - 你的状态值不会经常改变:)

此外,如果您担心枚举值的名称,那么可以通过将枚举值映射到资源文件中的字符串来解决这个问题,该字符串就是您在数据网格中显示的字符串或者通过UI浮现枚举的任何其他地方。如果你的业务专家正在改变枚举的定义(比如'1'现在意味着'准备'而'2'现在意味着'草案')那么这只是愚蠢而他们不应该这样做 - 如果他们是那么你无论如何都要重构你的代码。

答案 1 :(得分:0)

对我来说,枚举解决方案效果很好。向数据库添加新状态意味着应用程序遇到它时可能还需要做更多工作。例如,如果我添加PublishedDeleted状态会发生什么。