1

PersonH​​istories は ICollection であるため、次の linq2entities コードは FirstOrDefault 拡張機能の IEnumerable バージョンを呼び出しているように見えます。ただし、実行時には、実際には IQueryable バージョンを呼び出します。

var test = db.Persons.Where(d => d.PersonKey == 4)
        .Select(f => f.PersonHistories.FirstOrDefault());

私が抱えている問題は、使用しているカスタム クエリ プロバイダーがこの自動変換を実行せず、「...ICollection は IQueryable 型のパラメーターには使用できません」というエラーが表示されることです。したがって、これを回避するには AsQueryable を明示的に呼び出す必要がありますが、複雑なクエリの場合は非常に冗長になり、あまり DRY とは感じられません。

db.Persons.Where(d => d.PersonKey == 4)
        .Select(f => f.PersonHistories.AsQueryable().FirstOrDefault());

Linq 2 エンティティのビジター/プロバイダーのものを見つけようとして、フレームワークの参照ソースを掘り下げましたが、運がありませんでした (おそらく、オープンな参照ソースの一部ではありません)。 ベース プロバイダーは、この AsQueryable の暗黙的な使用をどのように達成するのでしょうか?


これらが式ツリーに変換されることは理解しています。Enumerable.FirstOrDefault がプロバイダーによって Queryable.FirstOrDefault に置き換えられることは理解しています。それが質問の前提です。

4

1 に答える 1

2

ベース プロバイダーは、この AsQueryable の暗黙的な使用をどのように達成するのでしょうか?

彼らはしません。あなたのコードは実際にはまったく実行されませんFirstOrDefault()呼び出しを表す式ツリーを構築しますが、それは直接実行されません。クエリ プロバイダーはそれを確認し、f.PersonHistories実際にはデータベース内のエンティティに基づいていることを判断し、クエリを適切に変換します。

于 2012-06-13T16:21:52.887 に答える