按位或定义 SqlBulkCopyOptions?
Bitwise OR to define SqlBulkCopyOptions?
所以我向我的一位高级开发人员寻求帮助,以找出与事务范围相关的问题,他来到我的办公桌前,对 SqlBulkCopy 和 SqlBulkCopyOptions 参数使用了不同的重载,他做了如下操作:
SqlBulkCopyOptions options = (SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.CheckConstraints);
现在可以使用了,但我不明白 bitwise or
在这里是什么意思。我以为我对它有所了解,从未真正使用过它,但是这种用法让我挠头。是的,我没有让我的前辈向我解释。我希望有人能帮助我理解该声明的作用。网上的大多数按位或示例都有一些数字,我得到了(我认为),但是这个?
enum
的原理与数字完全相同,因为 enum
的基础类型始终是整数类型。如果您查看 SqlBulkCopyOptions
的 declaration,您会发现其成员的基础值是 2 的幂,因此可以通过这种方式组合它们。
如果枚举具有 [Flags]
属性并且具有彼此独立的枚举值,则它可以用作标志:
SqlBulkCopyOptions
的定义在这里:https://github.com/Microsoft/referencesource/blob/master/System.Data/System/Data/SqlClient/SqlBulkCopyOptions.cs
忽略位移语法的使用。实际值为:
Name Hex Dec Pow 2 Binary
Default = 0 = 0 = 0 = 00000000
KeepIdentity = 1 = 1 = 1 = 00000001
CheckConstraints = 2 = 2 = 2 = 00000010
TableLock = 4 = 4 = 3 = 00000100
KeepNulls = 8 = 8 = 4 = 00001000
FireTriggers = 10 = 16 = 5 = 00010000
UseInternalTxn = 20 = 32 = 6 = 00100000
观察每个值都是 2 的下一个幂,这意味着在二进制中(最后一列)它们的位是完全互斥的。
这意味着您可以将它们组合在一起,让您看到每个值都已设置,例如,如果您想要 KeepIdentity
和 TableLock
,那就是 0x01
和 0x04
。我们使用 OR 运算符,但以每位为基础,这为我们提供了我们想要的行为:
二进制:
00000001
00000100 OR
--------
00000101
观察第一位和第三位现在如何 1
。
因此,(KeepIdentity | TableLock == 5
).
此方法不适用于不是 2 的幂的枚举值,例如,如果 KeepIdentity
的值为 1
而 CheckConstraints
的值为 2
但是 TableLock
的值为 3
,那么在二进制中它们是:
00000001 KeepIdentity
00000010 CheckConstraints
00000011 TableLock
观察到,通过分析 00000011
的位,无法确定这是 KeepIdentity
和 CheckConstraints
的组合,还是单个 TableLock
值。这就是为什么标记枚举值必须是:1. 2 和 2 的幂:互斥(shorthand 和组合值除外)。
所以我向我的一位高级开发人员寻求帮助,以找出与事务范围相关的问题,他来到我的办公桌前,对 SqlBulkCopy 和 SqlBulkCopyOptions 参数使用了不同的重载,他做了如下操作:
SqlBulkCopyOptions options = (SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.CheckConstraints);
现在可以使用了,但我不明白 bitwise or
在这里是什么意思。我以为我对它有所了解,从未真正使用过它,但是这种用法让我挠头。是的,我没有让我的前辈向我解释。我希望有人能帮助我理解该声明的作用。网上的大多数按位或示例都有一些数字,我得到了(我认为),但是这个?
enum
的原理与数字完全相同,因为 enum
的基础类型始终是整数类型。如果您查看 SqlBulkCopyOptions
的 declaration,您会发现其成员的基础值是 2 的幂,因此可以通过这种方式组合它们。
如果枚举具有 [Flags]
属性并且具有彼此独立的枚举值,则它可以用作标志:
SqlBulkCopyOptions
的定义在这里:https://github.com/Microsoft/referencesource/blob/master/System.Data/System/Data/SqlClient/SqlBulkCopyOptions.cs
忽略位移语法的使用。实际值为:
Name Hex Dec Pow 2 Binary
Default = 0 = 0 = 0 = 00000000
KeepIdentity = 1 = 1 = 1 = 00000001
CheckConstraints = 2 = 2 = 2 = 00000010
TableLock = 4 = 4 = 3 = 00000100
KeepNulls = 8 = 8 = 4 = 00001000
FireTriggers = 10 = 16 = 5 = 00010000
UseInternalTxn = 20 = 32 = 6 = 00100000
观察每个值都是 2 的下一个幂,这意味着在二进制中(最后一列)它们的位是完全互斥的。
这意味着您可以将它们组合在一起,让您看到每个值都已设置,例如,如果您想要 KeepIdentity
和 TableLock
,那就是 0x01
和 0x04
。我们使用 OR 运算符,但以每位为基础,这为我们提供了我们想要的行为:
二进制:
00000001
00000100 OR
--------
00000101
观察第一位和第三位现在如何 1
。
因此,(KeepIdentity | TableLock == 5
).
此方法不适用于不是 2 的幂的枚举值,例如,如果 KeepIdentity
的值为 1
而 CheckConstraints
的值为 2
但是 TableLock
的值为 3
,那么在二进制中它们是:
00000001 KeepIdentity
00000010 CheckConstraints
00000011 TableLock
观察到,通过分析 00000011
的位,无法确定这是 KeepIdentity
和 CheckConstraints
的组合,还是单个 TableLock
值。这就是为什么标记枚举值必须是:1. 2 和 2 的幂:互斥(shorthand 和组合值除外)。