2010-12-29 11 views
26

LINQプロバイダと新しいQueryOver構文を使用して、FluentNHibernateとNH 3.0で遊んでいます。今NHibernate 3.0:いいえFirstOrDefault()とQueryOver?

Result precedingOrMatchingResult = Session.QueryOver<Result>(). 
     Where(r => r.TimeStamp < timeStamp). 
     OrderBy(r => r.TimeStamp).Desc.     
     FirstOrDefault(); //get the preceding or matching result, if there is any 

、インテリセンスは何があることを私に伝えていない:

は今QueryOverと私は指定された値にできるだけ近く、しかし大きくないタイムスタンプ値を持つアイテム(と呼ばれる結果)を取得したいですFirstOrDefault()のようなものです。もちろん、私の注文したクエリを列挙し、LINQを使ってアイテムを取得することもできます。しかし、これはすべてのアイテムを最初にメモリにロードします。

FirstOrDefault()の代替手段がありますか、まったく間違ったことを理解していますか?値が見つからない場合

+0

ルック。 @RRRの答えを受け入れてください。 –

答えて

10

NH 3を一体化LINQプロバイダを持っている(:

+0

すごくいいよ、試してみよう(今年は去年だけど、今は去っているから!) – Marcel

+0

これはトリックだ。しかし、私のWhere節にはいくつかの追加の制限があるので、NHへのLINQはNullable型の.HasValue()メソッドのサポートをサポートしていないことがわかりました。あまりにも悪いですが、私は今チェック!= nullが動作します。 – Marcel

+8

これはQueryOver でこれを行う質問には答えません。答えは尋ねられた質問では有効ではありません。 @ RRRはより正確です。 – Jafin

9

Result precedingOrMatchingResult = Session.QueryOver<Result>(). 
     Where(r => r.TimeStamp < timeStamp). 
     OrderBy(r => r.TimeStamp).Desc. 
     SetFetchSize(1). 
     UniqueResult(); 

をお試しくださいUniqueResultは、まずまたはデフォルトが何をするかちょっとある、単一の値、またはnullを返します。

フェッチサイズを1に設定することは必須ではない場合もありますが、プロファイラーでテストします。

Result precedingOrMatchingResult = Session.QueryOver<Result>(). 
     Where(r => r.TimeStamp < timeStamp). 
     OrderBy(r => r.TimeStamp).Desc. 
     Take(1).List(). //enumerate only on element of the sequence! 
     FirstOrDefault(); //get the preceding or matching result, if there is any 
+0

私はそれを調べました。 UniqueResultはSingleOrDefaultと似ているようですが、私は単一の項目を持っていません。私にはリストがあり、最初のアイテムだけを選びたいと思う。 – Marcel

+0

質問を返すのは最初の項目だけです。なぜデータベースサーバーからリストを返してから、ほとんどの作業を捨てるのですか? –

35

は、私は今、そうのように、私は、リストにIQueryOverインスタンスを取る()拡張メソッド、およびのみ列挙を使用することができることを見出しましたクエリは内部的にHQL/SQLに変換されます)。その後、NHibernate.Linq名前空間を追加する必要がありますと: `SingleOrDefault()`のための

Result precedingOrMatchingResult = Session.Query<Result>(). 
    Where(r => r.TimeStamp < timeStamp). 
    OrderByDescending(r => r.TimeStamp). 
    FirstOrDefault(); 
+6

「テイク」は、私がお勧めするものです。これを 'List()。FirstOrDefault()'の代わりにRRRの 'SingleOrDefault'と組み合わせると完璧です。 –

+0

実際には '.Take(1)'は '.SetFetchSize(1)'と同じことを行います。どちらの場合も、一致するすべての結果についてクエリを実行しておらず、最初のものに対して列挙していません。 –

22
Result precedingOrMatchingResult = Session.QueryOver<Result>() 
              .Where(r => r.TimeStamp < timeStamp) 
              .OrderBy(r => r.TimeStamp).Desc 
              .SingleOrDefault(); 
+1

はい、これは正解です。 'SingleOrDefault()' –

+3

が原因でNHibernate.NonUniqueResultExceptionが発生する – Graham

+0

ユニークでない結果例外も発生します。 –

関連する問題