比較的大きくて複雑なデータモデルで、ObjectContextを使用してEntityFramework5を使用しています。複数のIQueryable.Include(Path)をチェーンして、関連するオブジェクトを熱心にロードするときに生成される大きなクエリを回避したいと思います。
たとえば、私は次のようなことをしています:
var queryPe = context.Person.Where(p => p.Id == 110).Include(@"AA");
queryPe = queryPe.Include(@"BB.CC.DD");
queryPe = queryPe.Include(@"EE.FF");
文字列配列を使用し、実行時にforeachループで各グラフをチェーン化することで、汎用化できます。
代わりに、私はこのようなことをしたいと思います:
Person pe = context.Person.Where(p => p.Id == 110).First();
context.LoadProperty(pe, "AA");
pe.BB.Attach(pe.BB.CreateSourceQuery().Include(@"CC.DD"));
pe.EE.Attach(pe.EE.CreateSourceQuery().Include(@"FF"));
1つの大きなクエリを使用する代わりに、4つの小さなクエリをデータベースにヒットさせます。もちろん、グラフパスの力を文字列として活用したいと思います。
私は間違っているかもしれませんが、これは、名前でナビゲーションプロパティを取得し、CreateSourceQuery()を実行するために、relexionを使用する必要があることを意味します。これを行うためのそのような拡張メソッドがないためです。
私は正しいですか?
編集1:ええと、私には追加の制約があります。つまり、Self Tracking Entities(STE)を使用しています。これは、関連オブジェクトがEntityCollectionまたはEntityReferenceとして実体化されないことを意味します。したがって、Attach()とCreateSourceQuery()は使用できません。
そのため、オブジェクトグラフを処理するためにContext.LoadPropertyで立ち往生しています。それだけが可能ですか?
EDIT 2:DbContextクラスの助けを借りて、EDIT1で明らかになった問題が解決されました。以下のコードを参照してください:
Person pe = context.Person.Where(p => p.Id == 110).First();
context.LoadProperty(pe, "AA");
DbContext dbc = new DbContext(context, false);
dbc.Entry(pe).Collection(@"BB").Query().Include(@"CC.DD").Load();
dbc.Entry(pe).Reference(@"EE").Query().Include(@"FF").Load();
編集32013年2月11日:上記のコードに問題があります(編集2)。パスの最後のエンティティがコレクションではなく参照である場合、コードは失敗しませんが、ロードされません:-(
編集4:リフレクションを使用する代わりに、現在、T4テンプレートを使用してエンティティデータモデルを確認することでコードを生成しています。