私はEF 4.3.1を使用しています... EF 4.x DbContext Generatorによって生成されたデータベースファーストのPOCOエンティティで4.4にアップグレードしたばかりです(問題は残ります) 。「Wiki」という名前の次のデータベースがあります(テーブルとデータを作成するSQLスクリプトはこちらです):
Wiki 記事が編集されると、レコードが更新される代わりに、新しいリビジョンが新しいレコードとして挿入され、リビジョン カウンターがインクリメントされます。私のデータベースには、「John Doe」という 1 人の著者がいて、「Article A」と「Article B」という 2 つの記事があり、記事 A には 2 つのバージョン (1 と 2) がありますが、記事 B には 1 つのバージョンしかありません。
遅延読み込みとプロキシ作成の両方を無効にしています (これは、LINQPad で使用しているサンプル ソリューションです)。名前が「John」で始まる人が作成した記事の最新版を取得したいので、次のクエリを実行します。
Authors.Where(au => au.Name.StartsWith("John"))
.Select(au => au.Articles.GroupBy(ar => ar.Title)
.Select(g => g.OrderByDescending(ar => ar.Revision)
.FirstOrDefault()))
これは間違った結果を生成し、最初の記事のみを取得します。
.FirstOrDefault()
次のクエリの.Take(1)
結果に置き換えることにより、クエリに小さな変更を加えます。
Authors.Where(au => au.Name.StartsWith("John"))
.Select(au => au.Articles.GroupBy(ar => ar.Title)
.Select(g => g.OrderByDescending(ar => ar.Revision)
.Take(1)))
驚くべきことに、このクエリは正しい結果を生成します (ただし、ネストが増えます)。
私は、EF がわずかに異なる SQL クエリを生成していると想定しました。一方は 1 つの記事の最新リビジョンのみを返し、もう一方はすべての記事の最新リビジョンを返します。2 つのクエリによって生成された見苦しい SQL は、わずかに異なるだけです (比較: .FirstOrDefault () の SQL と .Take( 1) のSQL を比較してください)が、どちらも正しい結果を返します。
.FirstOrDefault()
.Take(1)
(比較しやすいように列の順序を並べ替えています)
したがって、原因は生成された SQL ではなく、EF による結果の解釈です。EF が最初の結果を 1 つのArticle
インスタンスに解釈し、2 番目の結果を 2 つのArticle
インスタンスとして解釈するのはなぜですか? 最初のクエリが間違った結果を返すのはなぜですか?
編集: Connect に関するバグ レポートを開きました。この問題を修正することが重要だと思われる場合は、賛成票を投じてください。