実際にクエリを実行せずに、ネストされたリストをどのように遅延ロードしますか? 非常に基本的な例を使用すると、次のようになります。
class CityBlock {
IList<Building> BuildingsOnBlock;
Person BlockOwner;
}
class Building {
IList<Floor> FloorsInBuilding;
}
class Floor {
IList<Cubicle> EmployeeCubicles;
}
Class Cubicle {
System.Guid CubicleID;
Person CubicleOccupant;
}
そして、私のリポジトリレイヤーには、次のメソッドがあります。
GetCityBlocks()
次に、Service レイヤーに GetCityBlocksByOwner を配置します。ここで拡張メソッドを使用して、特定の人物が所有する都市ブロックを取得します。たとえば、Guido のブロックが必要だとします。
GetCityBlocks().ForOwner("Guido")
リポジトリで .ToList() を実行すると、クエリが実行されます。そのレベルで取得しているブロックが誰なのかわからないため、これはばかげています。問題は、これを効率的に行うにはどうすればよいかということです。
50000 のブロック所有者と 1000000 の都市ブロックがあり、それらすべてをロードすることはオプションではないと仮定しましょう。入れ子のため、IQueryables の使用は機能しません (少なくとも私が認識している極端なハッキングがなければ)。また、Rob Conery の LazyList のようなものを使用しようとすると、基本的に DAL からドメイン モデルへのリークが発生し、将来的には非常に悪い結果になる可能性があります。
では、これを正しく行うにはどうすればよいでしょうか。
- それは正しい文脈を決定することの問題ですか?もしそうなら、これをリポジトリ層で行うか、それともサービス層で行うか?
- 非常に具体的なサービス メソッドを取得するために、サービス レイヤーとリポジトリ レイヤーを半分融合させますか?
- それとも、何かが完全に欠けていますか?(とにかく段階的に廃止されているLinq2Sqlのことにはまだ比較的新しいので...)
編集: リポジトリ パターンでは、現在ドメイン オブジェクトにマッピングしているため、次のようになります。
public IQueryable<CityBlock> GetCityBlocks(){
var results = from o in db.city_blocks
let buildings = GetBuildingsOnBlock(o.block_id)
select new CityBlock {
BuildingsOnBlock = buildings,
BlockOwner = o.block_owner
};
return results;
}
これが機能するには、CityBlock オブジェクトの実際のフィールドを IQueryable にしない限り、建物に .ToList() を取得させる必要があります。 CityBlock.BuildingsOnBlock フィールドにアクセスするすべての人に付与されます。ドメイン オブジェクトへのマッピングは、サービス レイヤーで行う必要があるのでしょうか。