要約:エンティティの子コレクションのLINQクエリを取得して、「LINQ-to-Objects」ではなく「LINQ-to-Entities」を使用する、つまり、クエリプロバイダーを使用して生成するためのオプションは何ですか。通常の列挙を実行するのではなくSQL?これは、EF5、DbContext、およびPOCOエンティティを使用しています。
別の見方をすると、すべてのLINQクエリを変更せずに、エンティティの子コレクション(ICollection <>タイプ)を古いスタイルのEF1エンティティのEntityCollection <>プロパティのように動作させるにはどうすればよいですか?
これが私の状況です:
ObjectContextとデフォルトで生成されたエンティティの代わりにDbContextとPOCOエンティティを使用するように切り替えるEntityFramework5プロジェクトがあります。
コード全体で、次のようなクエリがあります。
var thirdEntities = from secondEntity in firstEntity.SecondEntities
select secondEntity.ThirdEntity;
firstEntity.SecondEntitiesのタイプはEntityCollectionであったため、これは以前はデータベースヒットが1つだけでした。これにより、LINQ to Entitiesが使用され、LINQステートメント全体がSQLに変換されました。
ただし、DbContextとPOCOの使用に切り替えた場合、上記のステートメントにより、データベースが多数ヒットするようになりました。問題の原因となるPOCOクラスプロパティは次のとおりです。
public class FirstEntity {
public FirstEntity() {
this.SecondEntities = new HashSet<SecondEntity>();
}
public virtual ICollection<SecondEntity> SecondEntities {get; set;}
}
これは、firstEntity.SecondEntitiesがタイプICollection(実際のタイプのHashSet)になっているためです。遅延読み込みがオンになっているため、データベースがヒットしてfirstEntity.SecondEntitiesを埋め、次にその結果がX回列挙されてsecondEntity.ThirdEntityの各インスタンスが埋められます。
私が見つけた解決策の1つは、最初のクエリを次のように変更することです。
var thirdEntities = from secondEntity in dbContext
.Entry(firstEntity)
.Collection(e => e.SecondEntities)
.Query()
select secondEntity.ThirdEntity;
しかし、私はこれをしたくありません。すべてのLINQクエリを変更する必要がないように、POCOをなんらかの方法で変更したいと思います。