Как использовать условие if для nullable boolean в linq to NHibernate - PullRequest
3 голосов
/ 26 марта 2012

У меня есть класс Person, свойство Sex которого можно обнулять.

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 имеет значение false или ноль.

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

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

Почему?

Ответы [ 2 ]

0 голосов
/ 08 мая 2014

Это ошибка в поставщике nhibernate linq, и обходной путь для нее будет таким:

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

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

0 голосов
/ 26 марта 2012

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

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

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

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

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

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

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

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