Как запросить объекты с определенным флагом enum, используя db int для его хранения - PullRequest
3 голосов
/ 17 марта 2012

У меня есть объект с перечислением Flag с несколькими возможными «использованиями». Флаг enum использует правильную степень 2.

Проверяя, есть ли у переменной определенный флаг, я могу сделать это, используя .NET 4 HasFlag()

НО:

Если я сохраню эту комбинацию флагов как int в базе данных ... как я могу получить объекты с определенным флагом при использовании Entity Framework?

Например, если мой объект относится к типу "Contact", я бы хотел запросить те из них, которые на самом деле являются "Клиентами и друзьями", являющимися флагами "Клиенты и друзья" в ContactType Перечислении.

Ответы [ 3 ]

4 голосов
/ 17 марта 2012
db.Contacts.Where(c => (c.Flag & MyEnum.Flag3) != 0).ToList();
2 голосов
/ 17 марта 2012

Вы можете получить объединенное битовое значение как int и сохранить это значение в БД в качестве столбца. Вот пример:

public enum MessagingProperties
{
    // No options selected (value is 0)
    None = 0x00,
    // messages are not discarded if subscriber is slow (value is 1)
    Durable = 0x01,
    // messages are saved to disk in case messaging crashes (value is 2)
    Persistent = 0x02,
    // messages are buffered at send/receive point so not blocking (value is 4)
    Buffered = 0x04
}

Чтобы объединить эти перечисления флагов, вы должны:

// combine the bit flags
var combinedFlags = MessagingProperties.Durable | MessagingProperties.Persistent | 
                     MessagingProperties.Buffered;

// this will be equal 7, no other combination can sum up to seven so it is unique, that's how bit flags work
int combinedFlagsInt = (int)combinedFlags;

Теперь вы можете пойти дальше и сохранить это значение в БД. Если вы хотите запросить несколько битовых флагов, вы:

  • объединить их
  • бросьте их в int
  • и использовать полученную переменную / значение в качестве фильтра в предложении Where.
2 голосов
/ 17 марта 2012

Я сомневаюсь, что у любого ORM будет способ адаптировать HasFlags к соответствующему коду SQL для вашей СУБД.

То, что вам, вероятно, понадобится, это либо написать хранимую процедуру, либо вручную запустить SQL-оператор, который будет выполнен для этого.

Вы не упоминаете, какую СУБД вы используете, но если я предполагаю, что вы используете SQL Server, вам повезло, поскольку у него есть оператор & (Побитовое И) .

Практический пример как T-SQL:

-- Setup Test Data 
DECLARE @Contacts TABLE (id int, contactType int, name nvarchar(MAX)) 

INSERT INTO @Contacts VALUES (1, 0, 'Fred'); -- Not Wanted
INSERT INTO @Contacts VALUES (2, 3, 'Jim');  -- Wanted
INSERT INTO @Contacts VALUES (3, 36, 'Mary');  -- Not wanted
INSERT INTO @Contacts VALUEs (4, 78, 'Jo');  -- Wanted

-- Execute Query
SELECT *
FROM @Contacts
WHERE ContactType & 2 = 2 
...