用位域枚举作将多个 Boolean 值存入数据库的同一个字段

 大家还记得文件的 FileAttribute 属性吗?它可以同时拥有多个值,如同时具有 ReadOnly、Hidden、System 这些属性,但它的类型只是一个枚举类型,那么它是如何实现同时具有多值的呢?

大家知道,枚举值的每一项的实际值只是一个数字,默认情况下每一项都是顺序赋值的,即第一项是0,第二项是1,第 n 项是 n-1。如果将这个类型的变量赋的值大于 n 的值,则无效。虽然无效,但是程序并不会出错,这时我们就想想,如果将这个变量赋一个特殊的值,比如说:某一枚举类型有 10 个项,值从 0 - 9,这时如果将该类型的变量赋值为 17,虽然该值不在枚举项中,但你可以把它当做最后两项值的和,因为除此之外其它任何两个项的值之和都不可能为 17,所以我们就可以把 17 当做同时包含了两个值。

对于上面的例子,虽然我们可以那样认为是包含了两个值,但实际上有很多的三个项的值之和都为 17,这样就无法确定它到底包含了哪些项。那么,要想实现这样的需求,就必须要求每一个值都是唯一的一个项组合,不能出现有两组项之和相等。这样对于任何一个值,要么非常明确它就是枚举中的某一项的值,要么就是哪几项值之和,绝不可能有第三种情况。

那么如果对枚举类型中的每一项定义值就成了关键。顺序定义值肯定不行,会出现不唯一的情况。那么该如何定义?从排列组合里的乘法原理可以得知,将每一项的值定义为 2 的幂(即 1、2、4、8 等),这就能保证组合的值都不会重叠。

例:
    Enum E颜色
        透明 = 0
        黑 = 1
        红 = 2
        绿 = 4
        蓝 = 8
    End Enum
当变量的值为 3 时,即包含黑、红;为 10 时,包含红、蓝;为 15 时,包含除透明外的所有项。

在 .Net 中,当使用 枚举变量.toString 时,会输出枚举项的名称,如上例中,值为 2 ,则输出“红”。但当变量的值不在枚举项中时,会直接输出数值,不是我们预期的输出所包含的项的名称,如当值为 3 时,会输出“3”而不是“黑,红”。当然, .Net 不会不想到这个问题,它提供了 FlagsAttribute 属性,在声明枚举类型时添加此属性即可。如上面的例子改为:
<FlagsAttribute( )> _
    Enum E颜色
        透明 = 0
        黑 = 1
        红 = 2
        绿 = 4
        蓝 = 8
    End Enum
这样在输出时会显示出所包含项的名称。当然,这个无关紧要,无非是显示的事,和我们需要的没关系。

好了,通过上面的描述,我们已经知道如何在一个值里存放多个值(看着这么矛盾-_-#),那么如何操作呢。还用上面的例子,具体操作如下:
Dim c As E颜色
添加:
c = c Or E颜色.黑

移除:
c = c Xor E颜色.黑

判断是否存在:
c And E颜色.黑 = E颜色.黑

OK!看到这儿大家应该明白了,判断是否存在就可以用来保存一个 Boolean 值了。比如需要将 10 个 Boolean 值存入数据库中的某字段,先将字段类型设为整型,再定义一个枚举类型,将这 10 项按 2 的幂的值定义到这个枚举类型中。若某个值为 True,则添加,否则就移除。检索值时用判断是否存在即可。

其实也不一定非要用枚举,只要按这个规则,自定义一个类更方便,如:

Public   Class  BooleanList
    
Private  _value  As  UInt64

    
Public   Sub  Add( ByVal  value  As  UInt64)
        _value 
=  _value  Or  value
    
End Sub

    
Public   Sub  Remove( ByVal  value  As  UInt64)
        _value 
=  _value  Xor  value
    
End Sub

    
Public   Function  Exist( ByVal  value  As  UInt64)  As   Boolean
        
Return  _value  =  _value  And  value
    
End Function

    
Public   Sub   New ( ByVal  value  As  UInt64)
        _value 
=  value
    
End Sub
End Class

 

有什么意义?

如果在开发过程中发现还需要在数据库中添加一个字段,这一定是非常令人痛苦的,要添加大量的代码。不过如果添加的是一个 Boolean 字段,就可以不用改动数据库了。比如,先前数据库的信息删除时都是直接删除,现在需要多一个回收站的功能,需要在数据库中添加一个字段,标识记录是否被删除;或者需要添加一个字段标识记录的审核状态等等,只需要定义一个私有变量,其值为2的N次方,或是在枚举中添加一项,然后再添加其属性即可,修改的只是业务层的代码,甚至可以在运行时动态添加,很是方便。而且在进行条件查询时是用位运算进行条件判断的,效率也非常高。缺点就是占用了更多的字节。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值