LINQ2SQL-ネストされたリストはどのように怠けていますか?
-
16-09-2019 - |
質問
クエリを実際に実行せずに、ネストされたリストを怠zyにしますか?非常に基本的な例を使用して、私が持っているとします:
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()
そして、サービスレイヤーでは、getcityblocksbyownerを持っています。ここでは、特定の人が所有する都市ブロックを取得するために拡張方法を利用しています。
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;
}
これが機能するには、CitalBlockオブジェクトの実際のフィールドをiQueryableにしない限り、建物に.tolist()を取得する必要があります。 CityBlock.BuildingsonBlockフィールドにアクセスした人に付与されます。このドメインへのマッピングは、サービスレイヤーで行う必要があることをオブジェクトにしていますか?
解決
あなたは、イリストの代わりにiQueryablesを返すことによってそれをします。
tolist()は、回心をilistに実行する必要があるため、クエリがすぐに実行されます。
iQueryablesを返している限り、レイジーロードは、データが実際に必要になるまで実行を延期する必要があります。つまり、tolist()が呼び出された場合。
現時点では参照が見つかりませんが、このようにすると、SQLからSQLへのLinqがサーバーに送信されるSQLを最適化する機会があることを理解しています。言い換えれば、最終的にこれらのレコードを読みます。
GetCityBlocks().ForOwner("Guido")
これらのレコードではなく:
GetCityBlocks()
他のヒント
ドメインオブジェクトをマッピングして機能させるために、別のアプローチを試してみることができます。問題は、あなたが何をしても(あなたがあなたのドメインオブジェクトのiQueryablesにあなたのリストを変更しない限り)、あなたがマッピング中にTolist()ingに終わることになるということです。
LINQ2SQLがカスタムデータコンテキストを作成し、マッピングにデザイナーを使用しないことによりPOCOSへのマッピングを行うことをお勧めします。このルートに入るには独自の問題がありますが、実行できます。
これがこのルートを始めさせるためのリンクです