2011-08-08 5 views
2

ページングのために作成しようとしているクエリがあります。ここでは、オブジェクトのコレクションを熱心に読み込み、そのオブジェクトのページリストを返します。以下のクエリは、我々はプロファイラで見たとき、それはスキップをスキップして、設定を取るために働く、とばかりオブジェクトのリスト(熱心にロードされた)を返していません:NH 3.1で呼び出しを呼び出すとSkipとTakeが無視されます

var result = _repostitory.All<MediaFile>() 
      .Skip(10) 
      .Take(10) 
      .Fetch(mf => mf.Tags); 

すべては、スキップをコンパイルし、実行しますがとテイクパートは無視され、すべてのデータが戻されます。フェッチをSkipとTakeと共に使用してページングを行うことは可能ですか?

答えて

2

あなたはスキップする前にフェッチし、(それがSQLないNHに関係している)私は、NHは、クエリの制限に積極的なロードに参加扱うことができない覚えているから

var result = _repostitory.All<MediaFile>() 
.Fetch(mf => mf.Tags)    
.Skip(10) 
.Take(10); 

を取る呼び出ししようとしています。しかし、それはサブセレクトで動作するかもしれません。

** UPDATE

TableA 
------------- 
Id|Value 
------------- 
1 |Value1 
2 |Value2 
3 |Value3 

TableB 
------------------------- 
ChildId|ParentId|ChildValue 
------------------------- 
1  |  1|Value1 
2  |  1|Value2 
3  |  2|Value3 
4  |  2|Value4 
5  |  3|Value5 
6  |  3|ValueA 
7  |  3|ValueA 
8  |  3|ValueA 



SELECT * FROM TableA LEFT JOIN TableB ON TableA.Id = TableB.ParentId 

Result 
-------------------------------------- 
Id|Value |ChildId|ParentId|ChildValue 
-------------------------------------- 
1 |Value1|1  |  1|Value1 
1 |Value1|2  |  1|Value2 
2 |Value1|3  |  2|Value3 
2 |Value1|4  |  2|Value4 
3 |Value1|5  |  3|Value5 
3 |Value1|6  |  3|ValueA 
3 |Value1|7  |  3|ValueA 
3 |Value1|8  |  3|ValueA 


SELECT TOP 2 * FROM TableA LEFT JOIN TableB ON TableA.Id = TableB.ParentId 

Result 
-------------------------------------- 
Id|Value |ChildId|ParentId|ChildValue 
-------------------------------------- 
1 |Value1|1  |  1|Value1 
1 |Value1|2  |  1|Value2 

この例を考えるため.Take(2)二人の子供(ID = 1)で一つのオブジェクトを返します。最初の2つのオブジェクト(Id 1,2)を子と一緒に戻したい場合に使用します。

+0

スキップして取る前にフェッチを入れてみました。私はまだ同じ結果を得ています。 Entity FrameworkにはIncludeという同等のメソッドがあるので、SQLの制限であってはなりません。 NHibernate LINQプロバイダに固有のようです。 –

+1

デフォルトではフェッチはSQL結合に変換されます。 ジョインは2つのテーブルのデカルト積を生成し、スキップ/テイクは親テーブルのみに適用する必要があります。これを行う唯一の方法は、親オブジェクト用と子オブジェクト用の2つのクエリを使用することです。他のものは間違った結果をもたらすでしょう。 EFがどのようにこの問題を処理しているかわかりません。 マッピングで、.Fetch.Subselect()&& .Not.LazyLoad()を使用して確認できます(Fluent Nhibernateを使用していると仮定します)。これにより、2つのSQLクエリが使用され、NH3の新しいLinqでそれを試したことはありません。 –

+0

Nhibernate基準オブジェクトは2つのクエリを実行せずにこの機能をサポートしています。私はなぜ結合がスキップとテイクに影響を与えるのかわかりません。例えば ​​"Take"は "select top x" SQL文に変換されます。これは、標準のselectまたはjoinで機能します。 –

関連する問題