2012-03-26 8 views
3

にLINQでNULL可能ブールのための条件は、私がSexプロパティがNULL可能であることをPersonクラスを持っている場合は使用方法。NHibernateの

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

そして、NHibernateへのlinqの問い合わせがあります。

dto.Sexの値がtrueの場合、結果は正しいです。

しかしdto.Sexの値は、結果はセックスが偽またはnullであることを人々が含まれているため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 

なぜ?

+1

私はこの例を確認しました。問題、と私は彼が本当にhymにいくつかの回避策が存在すると言うことができる:.Where(X => x.IsActive.HasValue && x.IsActive == false)を –

+0

@Adam:私はそれをkhowが、私は – Ehsan

+0

あなたよりよい解決策を探して"私の基本問題は生成されたクエリのタイプです"というコメントに書いてあります。この点について詳しく説明してください。私が見ているように、記述された問題はブール型でのみ存在します。 –

答えて

0

そのLINQクエリは、case文を生成し、なぜ私はそれは本当に奇妙だ、知らない...

しかし、私は個人的には、NULL可能ブールのアプローチが好きではありません。

ブールは、真または偽の2つの値を、持っています。あなたがそれをヌル可能にする瞬間、あなたはそれを可能な3番目の価値にしています。このようなシナリオでは

私はそれが列挙型を使用する方が良いと思います。

私はこの問題に対するより良いアプローチのような列挙型であると思われた場合には、「セックスは「男性」/「女性」のであると仮定します。

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

それはあなたのコードははるかに記述のようになりますうまく:

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

はあなたのソリューションをありがとうどこにhasValueはを使用して、修正NHibernateのコード:彼は誤ってSQLを生成して、私は2オプションを参照してくださいので、私にとってはNHibernateは、バグがあります。しかし、この質問の「Sex」プロパティは、例えばです。私の根本的な問題は生成されたクエリのタイプです。 – Ehsan

0

これは、NHibernateはLINQプロバイダでのバグがあり、それを回避するには、次のようになります:

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

このトリックは、偽の値または真の値を含むべきセットからのヌル値をフィルタリングすることです(真の値は問題ではないので、主に偽の値です)。