Возьмем такой сценарий: у вас есть несколько перечислений флагов в C #, привязанных (и фактически сгенерированных) к таблицам перечисления в SQL Server. Допустим, вы являетесь дистрибьютором и разрешаете своим посредникам указывать, в какие штаты США они отправляют. Будучи блестящим и элегантным инженером-программистом, вы реализовали это как битовое значение флага для экономии места хранения:
create table USState (
StateID bigint, StateAbbr char(2), StateName varchar(50))
/* insert all US States + DC into USState, StateIDs must be in powers of two */
/* StateID 0 reserved for 'None': */
create procedure GetStatesByFlag (@StateFlags bigint) as
declare @StateIDs table
(
StateID bigint,
primary key (StateID)
)
insert into @StateIDs
select StateID
from USState
where @StateFlags & StateID != 0
or (@StateFlags = 0 and StateID = 0)
select s.StateID, s.StateAbbr, s.StateName
from
USState s join
@StateIDs si
on si.StateID = s.StateID
Сладкое. Вы можете динамически включать / исключать как в SQL, так и в C #, используя побитовую логику, которая позволяет мгновенно гидрировать списки флажков и выбирать списки в Asp.NET, сохраняя при этом только одно 64-разрядное число для хранения любой комбинации выборов. И вам не нужен неиндексируемый оператор сравнения в предложениях WHERE ваших процедур, за исключением самой таблицы enum, которая имеет максимум 64 строки. Поиск в ваших дистрибьюторах всех, кто отправляет товары в Индиану и Калифорнию, все еще может использовать сравнение на равенство и индекс.
Теперь у вас есть запрос на добавление поддержки для территорий США, почтовых кодов вооруженных сил и канадских провинций, а также для обеспечения обратной совместимости. Там нет сокращения списка до <64 записей, и бизнес <em>действительно хочет избежать необходимости отделять государства старой школы от остальных территорий и округов.
Что ты делаешь?
Творческие ответы приветствуются, но реальная проблема здесь заключается в следующем: существует ли способ заставить ту же побитовую математику, которая работает с 64-разрядными значениями без знака, работать со знаковыми, используя отрицательное пространство для превышения 64 возможных битов, в обоих C # и SQL (2008)? Если это имеет значение, флаг имитируется, а не «настоящий» флаг, поэтому технически необязательно для этого работать с перечислением CLR с атрибутом [Flags].