2016-11-10 3 views
1

私は自己参照されるクラスを持っています。 IdModuloPaiはその親を指すキーであり、ModulosFilhosはそのオブジェクトの子です。C#オブジェクトの位置を再帰的に取得

私はプロパティProfundidadeを持っていますが、再帰的にそのオブジェクトの深さを計算します。

もう1つの重要な特性はOrdemです。そのスコープ内でユーザーが定義した順序を保持します。

Id Nome   IdModuloPai Ordem Profundidade OrdemGlobal 
1 Root   [NULL]  0  0    0 
2 Users   1   0  1    1 
3 Administration 2   0  2    2 
4 Logs   2   1  2    3 
5 Customers  1   0  1    4 
6 Orders   5   0  2    5 

この例の表を見てください。

Profundidadeに似た関数を作成しようとしています。その関数はグローバルな位置を計算しています。私は最後の列を取得しようとしていますOrdemGlobal。 OrdemGlobalによってオブジェクトを注文することができます。それは、必要なすべての地域で常に同じ方法で表示されます。この表に基づき

、正しい位置はどのように私は必要な動作をarchieveすることができ、管理がオルデン= 0を持っているとログがオルデン= 1

を持っているので、管理がログオンする前apperars

Root 
    +Users 
     +Administration 
     +Logs 
    +Customers 
     +Orders 

見ているのですか?私のクラスの

コードは以下の

public class ModuloModel 
{ 
    public int Id { get; set; } 
    public string Nome { get; set; } 
    public int Ordem { get; set; } 
    public virtual int Profundidade { 
     get 
     { 
      return GetDepth(this); 
     } 
    } 

    public int? IdModuloPai { get; set; } 
    public virtual ModuloModel ModuloPai { get; set; } 
    public virtual ICollection<ModuloModel> ModulosFilhos { get; set; } 

    private int GetDepth(ModuloModel moduloModel) 
    { 
     if (moduloModel == null) return 0; 
     if (moduloModel.IdModuloPai == null) return 0; 
     return GetDepth(moduloModel.ModuloPai) + 1; 
    } 
} 

EDIT:改善された質問

私がしようと試みています

public virtual int OrdemGlobal 
    { 
     get 
     { 
      return GetGlobalOrder(this); 
     } 
    }   

    private int GetGlobalOrder(ModuloModel moduloModel) 
    { 
     if (moduloModel == null) return 0; 
     if (moduloModel.ModuloPai == null) return 0; 

     int smallerSiblings = moduloModel.ModuloPai.ModulosFilhos.Where(x => x.Ordem < moduloModel.Ordem).Count(); 
     return (GetGlobalOrder(moduloModel.ModuloPai) + smallerSiblings + 1; 
    } 

しかし、これは混乱している、と戻っていないような何か所望の情報。

+0

GetGlobalOrderが返すものの例を挙げることができますか? –

答えて

1

あなたが望む順序に並べ替えるIComparer<ModuloModel>です。ここで

public class ModuloModelComparer : Comparer<ModuloModel> 
{ 
    public override int Compare(ModuloModel x, ModuloModel y) 
    { 
     //They are the same node. 
     if (x.Equals(y)) 
      return 0; 

     //Cache the values so we don't need to do the GetDepth call extra times 
     var xProfundidade = x.Profundidade; 
     var yProfundidade = y.Profundidade; 

     //Find the shared parent 
     if (xProfundidade > yProfundidade) 
     { 
      //x is a child of y 
      if (x.ModuloPai.Equals(y)) 
       return 1; 
      return Compare(x.ModuloPai, y); 
     } 
     else if (yProfundidade > xProfundidade) 
     { 
      //y is a child of x 
      if (x.Equals(y.ModuloPai)) 
       return -1; 
      return Compare(x, y.ModuloPai); 
     } 
     else 
     { 
      //They both share a parent but are not the same node, just compare on Ordem. 
      if (x.ModuloPai.Equals(y.ModuloPai)) 
       return x.Ordem.CompareTo(y.Ordem); 

      //They are the same level but have diffrent parents, go up a layer 
      return Compare(x.ModuloPai, y.ModuloPai); 
     } 
    } 
} 

がうまくいけば、これは正しい軌道に乗ってあなたを取得するのに十分である

class Test 
{ 
    public static void Main() 
    { 

     var root = CreateModel(1, "Root", null, 0); 
     var users = CreateModel(2, "Users", root, 0); 
     var administration = CreateModel(3, "Administration", users, 0); 
     var logs = CreateModel(4, "Logs", users, 1); 
     var customers = CreateModel(5, "Customers", root, 0); 
     var orders = CreateModel(6, "Orders", customers, 0); 


     List<ModuloModel> list = new List<ModuloModel> {root, users, administration, logs, customers, orders}; 

     list.Sort(new ModuloModelComparer()); 

     foreach (var moduloModel in list) 
     { 
      Console.WriteLine(moduloModel.Nome); 
     } 
     Console.ReadLine(); 
    } 

    private static ModuloModel CreateModel(int id, string Nome, ModuloModel moduloPai, int ordem) 
    { 
     var model = new ModuloModel {Id = id, Nome = Nome, IdModuloPai = moduloPai?.Id, ModuloPai = moduloPai, ModulosFilhos = new HashSet<ModuloModel>(), Ordem = ordem}; 
     moduloPai?.ModulosFilhos.Add(model); 
     return model; 
    } 
} 

それを使用してテストプログラムです。

+0

それは魅力のように働いた。大変ありがとう@Scott。 –

0

理由だけ

return this.Ordem; 

集約ルートがあるの?返しませんかクラスはそれ自体を参照しているので、それが持っているオーデムの価値を知る必要があります。それ以上のことは知らず、子供だけです。

関連する問題