1

実際にクエリを実行せずに、ネストされたリストをどのように遅延ロードしますか? 非常に基本的な例を使用すると、次のようになります。

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 フィールドにアクセスするすべての人に付与されます。ドメイン オブジェクトへのマッピングは、サービス レイヤーで行う必要があるのでしょうか。

4

2 に答える 2

1

ILists の代わりに IQueryables を返すことでそれを行います。

IQueryable から IList への変換を実行する必要があるため、ToList() によってクエリがすぐに実行されます。

IQueryables を返す限り、遅延読み込みは、データが実際に必要になるまで、つまり ToList() が呼び出されるまで実行を延期する必要があります。

現時点では参照が見つかりませんが、このようにすると、linq to sql はサーバーに送信する SQL を最適化する機会があると理解しています。つまり、最終的に次のレコードを読み取ります。

GetCityBlocks().ForOwner("Guido")

これらのレコードではなく:

GetCityBlocks()
于 2009-08-13T23:44:01.920 に答える
0

ドメインオブジェクトをマッピングして機能させるには、別のアプローチを試すことができます。問題は、何をしても (ドメイン オブジェクトでリストを IQueryables に変更しない限り)、マッピング中に ToList()ing を実行することになります。

もう 1 つの方法は、カスタム データ コンテキストを作成し、マッピングにデザイナーを使用しないことで、linq2Sql が POCO へのマッピングを実行できるようにする方法です:)、そうすれば、ドメイン モデルをクリーンに保ち、linq2Sql が適切なタイミングで依存関係を設定できるようになります。このルートに入ることには独自の問題がありますが、実行できることに注意してください。

このルートを開始するためのリンクは次のとおりです。

Linq to SQL で POCO を達成する

于 2009-08-14T00:40:09.273 に答える