2012-12-19 20 views
12

リポジトリインタフェースを実装する2つの異なるモデルに2つのデータコレクションがあります。それらのうちの1つは、Repositoryモデルに最適なフラットなリストにあります。他のデータモデルはツリー構造でフォーマットされており、構築したリポジトリインタフェースの実装は非常に日陰に見えます。私は第2のデータモデルを平坦化しようとすることができ、親に参照を使用するだけですが、現在、アプリケーションはツリー構造としてデータを取得できるという大きな利点があります。ツリー構造のデータモデルによるリポジトリパターンの実装

誰かがツリー構造のデータモデルでリポジトリパターンを実装した経験があるかどうかを知りたいですか?現在の私のGet(Func<T, bool> predicate)メソッドでは、リストを再帰的メソッドで平坦化し、LINQクエリでオブジェクトを返しますが、この実装は少しコストがかかるようです。

これを実装する方法についてのヒントがあれば幸いです。

これは、実装のsillineの説明に役立つ場合は、get by述語メソッドの実装です。

protected virtual IEnumerable<T> Get(Func<T, bool> predicate) 
{ 
    var objects = GetAll<T>(); 
    return objects.Where(predicate); 
} 

EDIT: いくつかのより多くのコード

private IEnumerable<TreeData> GetRecursiveObjects(TreeData object) 
    { 
     var allChildren = new List<TreeData>(); 
     allChildren.AddRange(object.Children); 

     foreach (var child in object.Children) 
     { 
      allChildren.AddRange(GetRecursiveObjects(child).ToArray()); 
     } 
     return allChildren; 
    } 

    protected virtual IEnumerable<T> GetAll<T>() 
    { 
     var objects = new List<T>(); 
     objects.AddRange(Objects); 
     foreach (var object in Objects) 
     { 
      objects.AddRange(GetRecursiveObjects(object)); 
     } 
     return objects.OfType<T>(); 
    } 

第二編集:

私はまた、リポジトリに要素を追加するための良い戦略がどうなるかについて少し困惑しています。私は、使用しているコードの親要素の子への追加を処理する必要がありますか、またはリポジトリは、要素とその親への参照の両方を取り、追加操作全体を処理する必要がありますか?

TL; DR

は、ツリー構造のデータとリポジトリのインターフェースを実装しようとすることは非常識ですか?

+1

あなたの質問に対する答えは、ツリーの構造と実際のデータの検索方法によって異なります。もう少し詳細を教えてください。 – James

+0

GetAllメソッドは子を再帰的にトラバースし、リストに追加します。 – Moriya

+0

ちょうど私の好奇心のために:なぜ構造を平らにすることを主張するのですか?なぜリポジトリは木のような構造を返せない/できないのでしょうか? –

答えて

4

イテレータブロック(yield return)を使用して、ツリーをウォークし、IEnumerable<T>を返すメソッドを記述できます。

その後、あなたは、あなたのツリーの内容の「フラット」コレクションを作成する必要はないだろうとあなたは自分の述語を適用するオブジェクトにLINQを使用することができます。実際には

protected virtual IEnumerable<T> Get(Func<T, bool> predicate) 
{ 
    return WalkAll().Where(predicate); 
} 

、LINQクエリwouldnをクライアントコードがそれを列挙するまで評価されることさえありません。

関連する問題