2016-11-24 5 views
1

と仮定私はNHibernateはにいくつかの事例でコレクションにLINQのようオラクルとNHibernateはへのLINQを使用して同じ動作を強制的にヌル

public class Man 
{ 
    public string Name {get;set;} 
    public string WifeName{get;set;} 
    public string OldestChildName {get;set;} 
} 

定義された男のクラスがあります。

Name |WifeName |OldestChildeName 
-------+-----------+----------------- 
Mike |Penny  |Jenny 
Bill |   |Julia  
Tom |Patricia |Patricia 
Peter |   | 
Bart |Mellany | 

への最も古い子の名前がwifesの名前と同じであるすべての人物を選択します。

var names = 
    from m in men 
    where m.WifeName == m.OldestChildName 
    select m.Name 

Lコレクションには、TomPeterが返されます。 しかし、NHibernateはにOracleへのLINQは、この変換:SQLの比較でnullに評価nullに、ヌルがfalseと評価:ちょうどトム返し

SELECT 
    m.name 
FROM 
    men m 
WHERE 
    m.WifeName = m.OldestChildName; 

私が生成してもらいたい何

ですので、LINQで私が入力する必要が

SELECT 
    m.name 
FROM 
    men m 
WHERE 
    m.WifeName = m.OldestChildName 
OR (
     m.WifeName IS NULL 
    AND m.OldestChildName IS NULL 
    ); 

var names = 
    from m in men 
    where m.WifeName == m.OldestChildName 
    || (m.WifeName == null && m.OldestChildName == null) 
    select m.Name 

をNHibernateはを伝えるための簡単な方法はあります2つのNULL可能な列の間の等価比較をSQL比較とNULLチェックに変換するには?

つまり、コレクションやデータベースに使用されているかどうかにかかわらず、同じlinqクエリを使用して同じ結果を得る方法はありますか?

私が考えることができるのは、式ツリーを解析してヌルチェックを発行するように変更するプリプロセッサを構築することでした。誰か既にこれをしていますか?

+0

"正しい" のあなたの考え方は間違っています。 SQLでは、nullは*別のnullと等しくありません。 1つの欠けている情報は、他の欠けている情報の一部とみなすことはできません。 –

+0

あなたが正しいです、私はタイトルを変更しました。 SQLでは、nullは「不明」と解釈され、未知数が未知数の場合は不明です。 C#ではnullは無価値として解釈されます。無価値は無価値と等しい。 私は両方の観点を理解しています。私の毎日の仕事では、ほとんどの現実の問題はC#の解釈に対応しています。だから私はクエリをこのように動作させる方法を探しています。 – realbart

+0

それは非常に悪い考えです。クエリは単にそのように動作しません。あなたは自分自身を混乱させ、コードの保守者を混乱させます。最悪の場合、答えが示すように、理由がわからなくても極端に遅いコードで終わるだろう –

答えて

-1

必要なSQLクエリ。

select * from Stack 
where COALESCE (wifeName,'')=COALESCE (OldestChildeName,'') 

出力。 enter image description here

Nhibernateのクエリオーバーを使用する必要があります。

var left = Projections.SqlFunction("COALESCE", 
NHibernateUtil.String, 
Projections.Property<Stack>(pc => pc.OldestChildeName), 
Projections.Constant("")); 


var right = Projections.SqlFunction("COALESCE", 
NHibernateUtil.String, 
Projections.Property<Stack>(pc => pc.WifeName), 
Projections.Constant("")); 

var restriction = Restrictions.EqProperty(left, right); 

var dd = contex.Session<Stack>().QueryOver<Stack>().Where(restriction).List(); 

出力。

enter image description here

enter image description here

ı suggest you lock

+0

これは、データベースサーバが* whole *テーブルをスキャンするように強制します。列に関数を適用すると、サーバーはインデックスを使用できなくなります –

+0

あなたはより良い提案がありますか? –

+0

ヌルチェックだけを使用してください。それには何も問題はありません。問題はある言語のセマンティクスを別の言語のセマンティクスに強制しようとすることです –