web-dev-qa-db-ja.com

NHibernate 3.0:QueryOverでFirstOrDefault()がありませんか?

LINQプロバイダーと新しいQueryOver構文を使用して、FluentNHibernateとNH3.0で遊んでいます。

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
_

さて、Intellisenseは、FirstOrDefault()メソッドのようなものはないと言っています。もちろん、注文したクエリを列挙してから、LINQを使用してアイテムを取得することもできます。ただし、これにより、最初にすべてのアイテムがメモリにロードされます。

FirstOrDefault()に代わるものはありますか、それとも完全に間違っていることを理解しましたか?

29
Marcel

NH 3には統合LINQプロバイダーがあります(クエリは内部でHQL/SQLに変換されます)。 NHibernate.Linq名前空間を追加してから、次の操作を行う必要があります。

Result precedingOrMatchingResult = Session.Query<Result>().
    Where(r => r.TimeStamp < timeStamp).
    OrderByDescending(r => r.TimeStamp).
    FirstOrDefault();
12
Diego Mijelshon

IQueryOverインスタンスでTake()拡張メソッドを使用でき、次のようにリストに列挙するだけでよいことがわかりました。

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
36
Marcel
Result precedingOrMatchingResult = Session.QueryOver<Result>()
                                          .Where(r => r.TimeStamp < timeStamp)
                                          .OrderBy(r => r.TimeStamp).Desc
                                          .SingleOrDefault();
22
RRR

試してみてください

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

UniqueResultは単一の値を返します。値が見つからない場合はnullを返します。これは、FirstまたはDefaultが行うことです。

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

10
tom.dietrich

SetFetchSize(1)が必要です。 LINQクエリが複数の結果を返す場合、クエリから返される結果は1つだけであると想定しているため、UniqueResult()を使用してNHibernate例外がスローされます。

0
hplodur