2012-01-20 10 views
2

を遅らせるように見えるdoes't。私はこの方法を使用する場合しかし、時々私はさらにそれをフィルタリングする:最初の1と第2のフィルタと同じSQLを生成し、選択NHibernateのIQueryableを、私はNHibernateは3.2を使用していると私がどのように見えるのリポジトリメソッドを持って実行

var models = MyRepository.GetActiveMyModel(); 
    var filtered = from m in models 
        where m.ID < 100 
        select new { m.Name }; 

は事実の後に行われなければなりません。 LINQの全体的なポイントは、必要なときに解明された式ツリーが形成されているため、データベース要求を保存してジョブの正しいSQLを作成できるということでした。

もしそうでなければ、私のリポジトリのメソッドはすべて、必要なものを正確に返さなければならないことを意味し、ペナルティを課さずにLINQをさらにチェーンの下で使うことはできません。

これは間違っていますか?

は以下のコメントに応答し

を更新:私は、最初のSQLを実行させる、私は結果を反復処理ライン、(アクティブ= 1)と第2のフィルタ(ID <を省略しました100)は明らかに.NETで行われます。また

、私は

var models = MyRepository.GetActiveMyModel(); 
var filtered = from m in models 
       where m.Items.Count > 0 
       select new { m.Name }; 

でコードの2番目のチャンクを交換した場合それはアクティブなレコードを取得するために、最初のSQLを生成し、それが持っているどのように多くのアイテムを見つけるために、各レコードに対して別々のSQL文を実行しますではなく、私が期待するような何か書く:あなたはメソッドからIEnumerable<MyModel>を戻ってきている

SELECT Name 
FROM MyModel m 
WHERE Active = 1 
    AND (SELECT COUNT(*) FROM Items WHERE MyModelID = m.ID) > 0 

アンソニー

+0

私は最も確かに、NHibernates IQueryablesあなたが何を意味するかわからないんだけど遅れて評価する。あなたは2つのデータベースクエリを取得し、1つを期待すると、例を与えることができますか?これらの例はいずれもQueryableを作成するだけであり、データベース要求をまったく生成してはいけません。 –

答えて

7

を、どの基になるシーケンスがIQueryable<MyModel>であっても、そのポイントからのメモリ内評価が行われます。

GetActiveMyModelの後にコードを追加してSQLクエリに追加する場合は、代わりにIQueryable<MyModel>を返します。

+0

ありがとうございます。私はそのばかだと信じられない! – littlecharva

+3

@littlecharva:たまには目の第二のセットがかかることがあります。 –

1

IEnumerableの拡張メソッド "IQueryable"の代わりに "Where"を実行しています。それはまだ遅れて評価され、同じ出力を与えますが、入力時にIQueryableを評価し、データベースに対してではなくメモリ内のコレクションをフィルタリングしています。

後で別のテーブル(カウント)に余分な条件を追加すると、条件について知る前にIQueryableを評価しているので、データベースからItemsコレクションのそれぞれとすべてを遅延取得する必要があります。

(はい、私はまた、代わりに仮想のメンバーであるとIEnumerableを上の大規模な拡張メソッドになりたい、しかし、残念ながら、そうではないよ)

関連する問題