将位枚举映射到SQL列值

8

我有一个位掩码枚举,其中设置了FlagsAttribute,像这样-

[FlagsAttribute]
public enum MyEnum
{
    None = 0,
    First = 1,
    Second = 2,
    Third = 4,
    Five = 8,
    Six = 16,
    Seven = 32,
    Eight = 64,
    Nine = 128
}

现在,我用C#将这个值存储到一个属性中,比如说MyProperty,在保存时,我会将该属性写入我的SQL数据库的整数列中。假设我从代码中选择了First,Second,Five,那么在数据库中它将被保存为'11'
我知道我可以从DB中获取值,然后只需要将int值强制转换为MyEnum,它就会给我相应的值。但是,我想在一些存储过程中对SQL数据进行一些操作,在这种情况下,我显然无法将其强制转换为枚举值。所以,有没有一种方法可以让我知道各个值。
例如,在示例中如果11被存储,任何一种方式可以让我将其显示为"1+2+8"吗?

你可以拥有varchar列,然后保存“1,2,8”吗? - Vivek
不,我不能更改数据库。它已经处于生产阶段了。 - Rohit Vats
SQL 在位运算方面表现不佳,建议在 C# 中进行操作。 - Jonathan Dickinson
@jonathan:什么?SQL在位运算方面很好。 - Joe
@Joe - 我的(SQL Server团队)消息来源说“可能没有你想象中那么好”,但这可能是那些边缘/微小优化的事情之一。 - Jonathan Dickinson
“Sources” 指的是 1 或 2 年前的 MSDN 博客文章。 - Jonathan Dickinson
4个回答

11

这可能有助于帮助您入门:

Select 11 & 1 As 'First'
  , 11 & 2 As 'Second'
  , 11 & 4 As 'Third'
  , 11 & 8 As 'Five'
  , 11 & 16 As 'Six'
  , 11 & 32 As 'Seven'
  , 11 & 64 As 'Eight'
  , 11 & 128 As 'Nine';

这将对每个已设置的值返回非零值(例如,Select 11 & 1 As 'First' 返回 1Select 11 & 2 As 'Second' 返回 2Select 11 & 4 As 'Third' 返回 0 等等)其中 11 是您存储的值。


我个人喜欢这种方法,因为它的实现明确。 - Aaron Anodide
是的,这会让我开始。谢谢你如此迅速的回复。 - Rohit Vats

6

您可以在SQL中执行按位运算


Select  *
From    MyTable
Where   MyEnum = (1 | 2 | 8)

返回设置了哪些标志

Select  Case when (MyEnum & 1) = 1 Then 1 else 0 End as First,
        Case when (MyEnum & 2) = 2 Then 1 else 0 End as Second,
        Case when (MyEnum & 4) = 4 Then 1 else 0 End as Third,
        Case when (MyEnum & 8) = 8 Then 1 else 0 End as Fourth,
        Case when (MyEnum & 16) = 16 Then 1 else 0 End as Fifth
From    MyTable

实际上,我的问题是我不知道这个组合。我只有一个值,比如说11,然后我想从中得到组合,即1+2+8。如果我有值133,我需要得到值“128+4+1”。 - Rohit Vats
如果您能给我一个小例子,那将非常有帮助。 - Rohit Vats
你的意思是什么?即哪些标志被设置了? - TheCodeKing

0
ID  Name
1   Zero
2   One
4   Two
8   Three
16  Four
32  Five

数值26(或11010)对应于One+Three+Four。要获取该描述,您可以使用下一个请求。

DECLARE @Names VARCHAR(8000) 
SELECT @Names = COALESCE(@Names + ' | ', '') + Name 
  FROM [Play].[dbo].[Enums]
  where (26 & ID)=ID
Select @Names;

它将会给你下一个结果 One | Three | Four

如果你只想获取ID

DECLARE @Names VARCHAR(8000) 
SELECT @Names = COALESCE(@Names + ', ', '') + STR(ID)
  FROM [Play].[dbo].[Enums]
  where (26 & ID)=ID
Select @Names;

0
declare @MyEnum as Int
set @MyEnum = 11
select
  case when ( @MyEnum & 1 ) = 1 then '1+' else '' end +
  case when ( @MyEnum & 2 ) = 2 then '2+' else '' end +
  case when ( @MyEnum & 4 ) = 4 then '4+' else '' end +
  case when ( @MyEnum & 8 ) = 8 then '8+' else '' end
  as Bitses

(可能的)尾随加号留给读者作为练习。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接