2009-07-29 13 views
2

私は、Lazy属性が付いていないプロパティを読み込もうとするdatamaクラスを持っています。私は2つのエンティティ、州と国を持っていますが、国はその国のすべての州のリストを含んでおり、州はその国が財産を持っているという点で国と前方関係を持っています。に割り当てられます。eager loading datamapperのフェッチ深さを制御するにはどうすればよいですか?

  1. 国家が
  2. マッパーが熱心財産国
  3. マッパーに達するマッパーによってロードされている状態のために国を取得している:私がしようとすると、これらのオブジェクトのいずれかを取得する場合は、これは何が起こるかである状態を言うことができます
  4. マッパーは
  5. マッパーが
  6. マッパーは、状態のリストをロードし、それができるキャッシュを使用して、個々の1をマッピングすることから始まる
  7. 国の熱心なコレクションプロパティに達した国にロードします。
  8. GOTO 1は国

にロードされた各状態のために、私はこのループを避けることができる方法についての損失でいます。だから私は主にアイデアを探しています。私は誰でも尋ねるコードを投稿しますが、このプロセスにはたくさんのコード行が含まれているので、コードで質問をあふれさせたくありません。

ありがとうございます!

編集:マット・ハウエルズのアドバイスに従い、Martin Fowler氏が実際に彼の提案は、空のオブジェクトを使用してにそれをロードすることですページ169の循環参照について話すと170んDataMapperのパターンを深く調査した後

よしアイデンティティマップを作成し、それを返して、再帰的ロードを停止する。私は約1000回この段落を読んだことがありますが、これがロードをどのように停止させるのか、また、この空のオブジェクトをいつアイデンティティマップにロードするのか、いつ、どのように失われるのか、まだ分かりません。私はここで濃密であることをお詫びしますが、これはちょうど私の頭の上を飛んでいるようです。

もう一度おねがいします。

答えて

2

どのオブジェクトがロードされたかを追跡するリポジトリを通じてオブジェクトをロードすることを検討してください。

編集:あなた自身のORMを(あなたがいなくても)しているなら、私はMartin Fowlerの著書「Enterprise Application Architectureのパターン」を強くお勧めします。私は漠然とこの本の中のこのループの状況について話しているので、あなたを助けるかもしれません。

編集2: ループのステップ4と5では、既に国を読み込んでいる場合は、既に読み込まれているため状態を熱心に読み込む必要はありません。これにより、無限ループが解消されます。

+0

私は実際に読み込まれたすべてのオブジェクトを追跡しています。しかし、私はちょうど密集していると思う、私はこれを利用できる方法を見ることができません。フェッチの深さを制御しようとしていますが、発信者固有の制御が必要です。私が達成しようとしているのは基本的には州(創始者) - >国 - >州 - > [STOP]ですが、私が州内にある個々の州ごとに地図を作成すると、 。だから、オリジネーターに特有のカウンターを適用しているようだが、それは疑問から外れているようだ。はい? – joshlrogers

+0

私は職場の机の上に置いて、明日何かを見つけることができるかどうかを見ます。ありがとうございました。 – joshlrogers

+0

私はMartin Fowlersのアドバイスを追加しましたが、私はまだ失われています。何かアドバイス? – joshlrogers

1

datamapperは循環参照をキャッチする必要があります。それは自家製のデータマッパーですか?

+0

私はこれをどうやってキャッチするのですか?それが私のdatamapperコードを調整して、これを監視するのを忘れているところです。 – joshlrogers

+0

すでに訪問したプロパティを記録し、現在のプロパティとそのリストを比較します。 – EricSchaefer

+0

したがって、フェッチの深さは通常、オブジェクトレベルではなくプロパティレベルで実装されますか?だから、私の最大フェッチの深さは3だから、プロパティを3回マッピングすることができますが、オブジェクトグラフの深さはそれよりもはるかに大きくなる可能性があります。私はその前提で正しいのでしょうか? – joshlrogers

0

私が思いついた解決策を投稿したかっただけですが、この猫には多くの方法があります。最大の深さに達するかいないされたフェッチするかどうかを伝えるブール値を返しますIncrementCounter

public static class FetchDepthCounter 
{ 
    private static Dictionary<Type, int> _DepthCounter; 
    private static int _MaxDepth = 3; 

    static FetchDepthCounter() 
    { 
     _DepthCounter = new Dictionary<Type, int>(); 
    } 

    public static void SetDepth(int depth) 
    { 
     _MaxDepth = depth; 
    } 

    public static void ResetCounter() 
    { 
     _DepthCounter.Clear(); 
    } 

    public static bool IncrementCounter(Type entityType) 
    { 
     if(!_DepthCounter.ContainsKey(entityType)) 
     { 
      _DepthCounter.Add(entityType, 0); 
      return true; 
     } 

     if(_DepthCounter[entityType] < _MaxDepth) 
     { 
      ++_DepthCounter[entityType]; 
      return true; 
     } 

     return false; 
    } 

} 

は、ここに私が作成した私のFetchDepthCounterClassです。私は、プロパティの値を設定する直前に、マッピングプロセスの一部としてインクリメントカウンタを呼び出します。最初に、私がロードする必要があるのは、別のDTOオブジェクトまたはDTOのコレクションであり、親の型とその型にインクリメントすることです。これは私のデータマッパーのSetValueメソッドの中にある小さなコードです:

if(isDto) 
{ 
    if (!FetchDepthCounter.IncrementCounter(property.ComponentType)) 
     return; 
} 

それはそうです。私のユニットテストはすべて合格です。誰もが助けてくれてありがとう。私はこれが後で誰かを助けることを望む。もう一度、これは作業パターンの単位でラップする方がはるかに簡単だったでしょうが、最終的にはそうするかもしれませんが、今は仕事が終わってしまいます。

関連する問題