2017-06-08 8 views
1

連鎖LINQクエリを以下のように実行しています。私はquery.ToList();の遅さの原因を調べようとしています。 SQLクエリは高速(ミリ秒)ですが、コードには1分かかります。チェーニングの理由は、リポジトリ機能を再利用するためです。LINQクエリを連鎖させるときの遅さ

  1. ここで遅い理由はありますか?
  2. これをどのように最適化できますか?
  3. query.ToList();を実行しているときに実行される実際のSQLクエリを確認するにはどうすればよいですか?

    //Client 
    var query = _service.GetResultsByStatus(status, bType, tType); 
    var result = query.ToList(); //takes a long time to execute 
    
    //Service function 
    public IEnumerable<CustomResult> GetResultsByStatus(string status, string bType, string tType) { 
        IEnumerable<CustomResult> result = null; 
        result = repo.GetResults(bType).Where(item => item.tStatus == status && (tType == null || item.tType == tType)) 
         .Select(item => new CustomResult { 
          A = item.A, 
          B = item.B, 
         }); 
        return result; 
    } 
    
    
    // Repository Function (reused in many places) 
    public IEnumerable<my_model> GetResults(string bType) { 
        return from p in dbContext.my_model() 
         where p.bType.Equals(bType) 
         select p; 
    } 
    

答えて

4

あなた.Where(item => item.tStatus == status && (tType == null || item.tType == tType)).Selectは、あなたのPC上で「ローカル」行われている...役に立たない行と列のトンは、あなたのPC上で「フィルタ」するためにSQLによって返されます。

public IEnumerable<my_model> GetResults(string bType) { 
    return from p in dbContext.my_model() 
     where p.bType.Equals(bType) 
     select p; 
} 

public IQueryable<my_model> GetResults(string bType) { 

に変更し、それを通常IEnumerable<>IQueryable<>は "下流LINQは、サーバ上で実行されます" という意味、 "下流LINQをローカルに実行されます" という意味。この場合、WhereSelectは、IEnumerable<>のクエリの変換の「下流」にあります。 IQueryable<>IEnumerable<>に変換することは可能ですが(容易にできますが)、その逆は通常不可能です。 AsQueryable<>はローカルで実行される "擬似" IQueryable<>を作成し、主に単体テストに役立ちます。

+0

説明をいただきありがとうございます。このソリューションは魅力的に機能しました。 IEnumerableを持つ考えは、遅延実行には十分でした。 – devnull

+0

@devnull 'IEnumerable <*' * is * "遅延実行" ... "Where"と "When"は直交する概念です。配列/リストvs IQueryable/IEnumerableは、IEnumerableとIQueryavbleがどこにあるか – xanatos

関連する問題