2012-03-26 1 views
3

У меня есть класс Person, который имеет свойство Sex.Как использовать, если условие для nullable boolean в linq для NHibernate

public class Person 
{ 
    public bool? Sex {get; set;} 
} 

И у меня есть запрос linq к NHibernate.

var q = SessionInstance.Query<Person>(); 

if (dto.Sex != null) 
    q = q.Where(p => p.Sex == dto.Sex); 

return q.ToList(); 

Теперь, если значение равно dto.Sex true, правильный результат.

Но если значение dto.Sex равно false, результат не верный, потому что в результате есть люди, которые Sex являются ложными или нулевыми.

Я проверил профилировщика для этого запроса:

select * from Person_Person person0_ 
where case 
      when person0_.Sex = 1 then 1 
      else 0 
      end = case 
        when 0 /* @p0 */ = 1 then 1 
        else 0 
       end 

Почему?

+1

Я проверил этот пример, потому что я не осознавал этого проблема, и я могу сказать, что он действительно существует hym некоторое обходное решение: .Where (x => x.IsActive.HasValue && x.IsActive == false) –

+0

@Adam: Я так понимаю, но я ищу для лучшего решения – Ehsan

+0

You написал в комментарии «Моя базовая проблема в типе сгенерированного запроса», можете ли вы подробнее остановиться на этом вопросе. Как я вижу, описанная проблема существует только с типом bool. –

ответ

0

Я не знаю, почему это LINQ запрос генерирует случай заявление, что это действительно странно ...

Но лично мне не нравится подход обнуляемого булево.

Булев имеет 2 значения, истинные или ложные. В тот момент, когда вы сделаете его нулевым, вы даете ему 3-е возможное значение.

В таком сценарии я думаю, что лучше использовать Enum.

Я предполагаю, что «секс» для «мужской»/«Женский», в этом случае я думаю, что лучший подход к проблеме является перечисление как:

public enum SexEnum 
{ 
    Unspecified = 0, 
    Male = 1, 
    Female = 2 
} 

Это делает код гораздо более информативными хорошо:

var males = session.Query<Person>().Where(x => x.Sex == SexEnum.Male); 
+0

Благодарим вас за решение. Но свойство 'Sex' в этом вопросе, например. Моя основная проблема заключается в типе сгенерированного запроса. – Ehsan

0

Это ошибка в NHibernate поставщика Linq, и обходной путь для него будет выглядеть следующим образом:

if (dto.Sex != null) 
    q = q.Where(p => p.Sex == dto.Sex && p.Sex != null); 

Фокус в том, чтобы отфильтровать значения с нулевым значением из набора, которые должны содержать ложные значения или истинные значения (истинные значения не имеют проблемы, так что это в основном для ложных значений)