0


0

Entity Frameworkを使用する場合、IEnumerable <T>関数の呼び出しの順序は最終的なクエリに影響しますか?

Entityフレームワークでは、ステートメントは

MyDataContext.Products.OrderByDescending( (p) => p.Id ).GroupBy( (p) => p.ProductId ).Select( (g) => g.FirstOrDefault()).Where( (p) => p.Name.Equals("Something") );

よりも別のデータベースクエリが発生する

MyDataContext.Products.Where( (p) => p.Name.Equals("Something") ).OrderByDescending( (p) => p.Id ).GroupBy( (p) => p.ProductId ).Select( (g) => g.FirstOrDefault());

つまり、Where()とGroupBy()の呼び出しの順序は、dbへの最終的なクエリに影響しますか? または、エンティティフレームワークはこれを解決するのに十分スマートですか?

私が疑問に思うのは、私が開発しているシステムでは、製品の列に対するすべての変更を追跡する必要があるからです。 これを実現するために使用するソリューションは、テーブルを更新するのではなく、新しい製品行を挿入することです。 製品の異なるバージョンは、「ProductId」フィールドを使用してグループ化されます。 したがって、「グループ化」ロジックを外部メソッドに移動したいのですが、呼び出し元がWhere条件を指定できるようにしたいので、私の目的は最初のアプローチを使用することです。

1 Answer


1


はい、それは重要です。 EFは、「Where」呼び出しの前に来る「OrderBy」呼び出しを静かに無視することがあります これは驚くべきことではありません。SQLクエリは、サブクエリの外で、「WHERE」の前の「ORDER BY」をすべてサポートしないためです。

次の点を考慮しても、「「グループ化」ロジックを外部メソッドに移動することはできますが、呼び出し元はWhere条件を指定できます」

var q = SomeQuery
        .Where(GeneratePredicate())
        .GroupBy(GenerateSelector());

次のようなメソッドがある場合:

public Expresssion> GeneratePredicate
{
     return e => e.Id == 123;
}

public Expression> GenerateSelector()
{
     return e => e.GroupField;
}

重要なのは、これらの Where`および GroupBy`呼び出しは `IEnumerable`の* not *メソッドです。これらは「IQueryable」のメソッドであるため、まったくSQLに変換できます。