7

次の LINQ クエリがあります。

var queryGroups = (from p in db.cl_contact_event
                   select new Groups { inputFileName = p.input_file_name }).Distinct();

実行すると、次のように変換されます。

SELECT 
[Distinct1].[C1] AS [C1], 
[Distinct1].[input_file_name] AS [input_file_name]
FROM ( SELECT DISTINCT 
       [Extent1].[input_file_name] AS [input_file_name], 
       1 AS [C1]
       FROM [mel].[cl_contact_event] AS [Extent1]
)  AS [Distinct1]

サブセレクトがある理由は、() で囲まれたベース LINQ クエリがあり、.Distinct() を実行しているためだと確信していますが、これを確認するのに十分な LINQ について知りません。それが実際に当てはまる場合、サブ選択が発生しないようにクエリを再構築/コーディングする方法はありますか?

私はおそらくここでつまらないことをしているように見えることを知っていますが、私はただ興味があります.

4

2 に答える 2

4

私はこの特定の状況についてはまったく心配しません。SQL Server(およびほとんどの場合エンタープライズデータベース)は、とにかく外部のSelectステートメントを最適化します。このSQLステートメントが生成される理由は、これが最も一般的で再利用可能なステートメントであるためであると私は理論付けます。私の経験から、これは常にに発生しDistinct()ます。

于 2012-06-18T22:35:11.940 に答える
4

これで、サブクエリの実際の根本原因は匿名型コンストラクターにあると思われます。既知のエンティティを選択するのではなく、他のエンティティ値から構築された任意のオブジェクトを選択するため、EF パーサーは、単一のテーブル、結合されたテーブル、計算フィールドなどから、フィールドの正確なセットを生成できることを確認する必要があります。サブクエリなど。式ツリー パーサーは、可能な限り LINQ クエリから SQL ステートメントを作成するのに非常に優れていますが、全知というわけではありません。常に最適な結果とは限りませんが、体系的な方法でクエリを処理し、常に正しい結果を生成します (要求したものが得られるという意味で)。

副選択を排除するためにクエリを書き直す限り、まず、匿名型を排除して正しい結果を生成する明確な方法がわかりません。しかし、もっと重要なことは、私が気にしないことです. Sybase のような最新の SQL サーバーは非常に賢く (多くの場合、開発者よりも賢く)、クエリから最適なクエリ プランを生成するのが得意です。それに加えて、EF はサブクエリが大好きです。サブクエリは、複雑なクエリを自動化された方法で作成するための非常に優れた方法だからです。LINQ クエリが使用されていない場合でも、それらを見つけることがよくあります。クエリからそれらをすべて排除しようとすると、すぐに無駄になります。

于 2012-06-18T23:28:00.200 に答える