2

私は次のような方法がありません。何らかの理由でメソッドチェーンは、出力正しいSQL

 private IEnumerable<CTNTransactionsView> RetrieveCTNTransactionsNotInTLS() { 
     IQueryable<int> talismanIdCollection = this._cc.TLSTransactionView.Select(x => x.kSECSYSTrans); 
     return this._cc.CTNTransactionView 
        .Where(x => !talismanIdCollection.Contains(x.kSECSYSTrans)); 
    } 

    public IEnumerable<CTNTransactionsView> RetrieveCTNTransactionsNotInTLSPast24Hours() { 
     DateTime previousDate = DateTime.Now.Date.AddDays(-1.0); 
     return this.RetrieveCTNTransactionsNotInTLS() 
        .Where(x => x.dSECSYSTimeStamp >= previousDate); 
    } 


    public IEnumerable<CTNTransactionsView> RetrieveCTNTransactionsNotInTLSPast24HoursVersionTwo() { 
     DateTime previousDate = DateTime.Now.Date.AddDays(-1.0); 
     IQueryable<int> talismanIdCollection = this._cc.TLSTransactionView 
                .Select(x => x.kSECSYSTrans); 
     return this._cc.CTNTransactionView 
        .Where(x => !talismanIdCollection.Contains(x.kSECSYSTrans)) 
        .Where(x=> x.dSECSYSTimeStamp >= previousDate); 
    } 

を、Entity Frameworkの6によって生成されたSQL出力結果と一致していません。

RetrieveCTNTransactionsNotInTLSPast24HoursVersionTwo()メソッドは、適切に次を持つSQL OUTPUT文を与える:

select ...... from ... where ...  AND ([Extent1].[dSECSYSTimeStamp] >= @p__linq__0)} 

私はSQLステートメントの出力を表示するときに、他の一つはdSECSYSTimeStamp用のフィルタを持っていません。

私が比較しているメソッドは、RetrieveCTNTransactionsNotInTLSPast24Hours()とRetrieveCTNTransactionsNotInTLSPast24HoursVersionTwo()です。

私はVSを使用してSQLを比較し、Debug.Writeline()をコンテキスト内のDatabase.Logに接続しました。

デバッグしてSQL出力を見ると、日付フィルタが含まれているように見えますが、もう一方はそうではありませんが、どちらも正しい結果を示しています。

私は、次を使用してから(出力をブレークポイントと見て)SQLを見て試してみました:

 System.Diagnostics.Debug.WriteLine("Running first method"); 
     var result = this.repo.RetrieveCTNTransactionsNotInTLSPast24Hours(); 
     var count = result.Count(); 
     System.Diagnostics.Debug.WriteLine("Running Second method"); 
     var resultTwo = this.repo.RetrieveCTNTransactionsNotInTLSPast24HoursVersionTwo(); 
     var count2 = resultTwo.Count(); 

私はEF 6.0を使用しています。

注:結果は全く同じで、同じ結果を出力します。しかし、私は興味があり、SQL Generatedが同じではない理由を理解したいと思いますか?

私は、あなただけで、すぐにそれを使用するクエリ式を定義ではなく、この時点で、私は LINQの、式の最後に .ToList()が追加されますが、あなたは List<kSECSYSTrans>のように右の型にメソッドの戻り値の型を変更することがあると思う
+2

LINQはIQueryableで使用されているときにのみLINQ to SQLを使用するためです。 'RetrieveCTNTransactionsNotInTLS'はIEnumerableを返します。これは、その時点でメモリにデータをロードした後、メモリ内のデータに対して2番目の 'Where'演算を行います.SQL文を変更することではありません。 – David784

答えて

1

問題は、メソッドからIEnumerableを返すことです。これを行うと、SQLを強制的に実行して(フィルタリングなし)、C#を使用して2番目のクエリを実行します。内部クエリを変更してIQueryableを返します。これにより、未実行の式ツリーが2番目のクエリに渡され、2番目のクエリが実行されるときに評価されます。

すなわち

private IQueryable<CTNTransactionsView> RetrieveCTNTransactionsNotInTLS()

あなたはその後、同じSQLを取得する必要があります。

+0

これは必ずしも可能ではないと付け加えるべきです。このようなフィルタを構築するときに本当に間違えるのは、実際にクエリを評価する前にSQL接続を閉じることができないということです。 IQueryableを返すがコードの後半まで評価しないと、この問題が発生する可能性があります。 – Spence

0

この操作の前に。私はめったにタイプIEnumerableを使用しません。

関連する問題