抽象エンティティ/クラスで構築された EF4 モデルがあります。
StateエンティティにCountryというナビゲーション プロパティがあることに注目してください。
注: 遅延読み込みが無効になっているため、オンデマンドで熱心に読み込む必要があります。
さて、次の方法がある場合:
public Location FindSingle(int id)
{
return _repository.Find().WithId(id).SingleOrDefault();
}
デフォルトでは、関連付けは返されません。しかし、明示的にしたいときに、どうすればアソシエーションを動的にeager-loadできますか?
これはできない:
return _repository.Find().WithId(id).Include("Country").SingleOrDefault();
「Country」というナビゲーション プロパティを持たないLocationという抽象クラスを使用しているためです。で実際にクエリを実行するまで、派生型が何であるかはわかりません.SingleOrDefault
。
だから、ここに私がしなければならなかったことがあります:
public Location FindSingle(int id, bool includeAssociations = false)
{
var location = _repository.Find().WithId(id).SingleOrDefault();
return includeAssociations
? LoadAssociation(location)
: location;
}
private Location LoadAssociation(Location location)
{
// test derived-type, e.g:
var state = location as State;
if (state != null)
return _repository.Find().OfType<State>().Include("Country").WithId(id).SingleOrDefault();
}
基本的に、私は2つの同一の呼び出しを行っています。それは機能しますか?はい。それはきれいですか?いいえ、実際には「熱心な読み込み」ではありません。
これが正しい解決策ではないことはわかっています。適切な解決策を考えてもらえますか? (はい、ストアド プロシージャを使用できることはわかっていますが、ここでリポジトリ/モデルを実際に調べたいので、エンティティがグラフに正しくアタッチされ、編集の準備ができています)。
Left Outer Joinが.Include
発生しますが、問題は「場所」エンティティ セットで作業していることです。「州」を必要と.Include
しますが、「州」は「場所」エンティティ セットに属します (派生クラスは親のエンティティ セットに属します)。
したがって、私の質問は実際にはかなり一般的なものだと思います-子が何であるかが事前にわからない場合、抽象エンティティの子に.Includeを行うにはどうすればよいですか?
.OfType<T>()
T が何であるかがわからない (呼び出しコードもわからない) ため、最初に (そして派生型の .Include を)使用できないことを覚えておいてください。したがって、ここではジェネリックを使用できません。