2009-07-22 7 views
2

私は過去数ヶ月間NHibernateにLinqを使ってwebappを開発してきましたが、今まで生成したSQLをプロファイリングしていません。 NHプロファイラを使用すると、Linq式が実行されると、次のコードのチャンクがDBに3000回以上ヒットするように見えるようになります。1回のリクエストでLinqが3,000以上のSQL文を生成するNHibernateに!

リポジトリ方法がどのように見える
 var activeCaseList = from c in UserRepository.GetCasesByProjectManagerID(consultantId) 
          where c.CompletionDate == null 
          select new { c.PropertyID, c.Reference, c.Property.Address, DaysOld = DateTime.Now.Subtract(c.CreationDate).Days, JobValue = String.Format("£{0:0,0}", c.JobValue), c.CurrentStatus }; 

public IEnumerable<Case> GetCasesByProjectManagerID(int projectManagerId) 
    { 
     return from c in Session.Linq<Case>() 
       where c.ProjectManagerID == projectManagerId 
       select c; 
    } 

CompletionDateがnullであるかどうかをチェック結果のすべてを反復処理し、その後、最初の初期リポジトリのクエリを実行するために表示されますが、発行最初にc.Property.Addressを取得するためのクエリ。

したがって、最初のクエリで2,000レコードが返された場合、そのうちの5つだけがCompletionDateを持たなくても、SQLクエリを実行して2,000レコードのアドレスの詳細を戻します。

SELECT ... WHERE ProjectManager = @:

私はこれが仕事と想像していたにせよ、それはWHEREのすべてを評価し、句を選択して、単にそれらを合併するので、initalクエリは次のようになるだろうということですp1 AND CompleteDateがNULLでない

これは5レコードを生成し、さらに5つのクエリを発行してアドレスを取得する可能性があります。私はここであまりにも多くを期待していますか、私は単に何か間違っていますか?

アンソニー

答えて

6

変更GetCasesByProjectManagerIDの宣言:

public IQueryable<Case> GetCasesByProjectManagerID(int projectManagerId) 

あなたはIEnumerable<T>でクエリを作成することはできません - 彼らはただのシーケンスです。 IQueryable<T>は、このような構成のために特別に設計されています。

+0

乾杯、それははるかに良い! – littlecharva

0

私はまだコメントを追加できません。 Jon SkeetはIQueryableを使いたいと思っていますが、これはLinqプロバイダがSQLを遅延構築することを可能にします。 IEnumerableは熱心なバージョンです。

関連する問題