2016-11-10 7 views
1

Ich habe eine Klasse, die selbst referenziert ist. IdModuloPai ist der Schlüssel, der auf seine Eltern verweist, und ModulosFilhos ist die Kinder dieses Objekts.C# Position des Objekts rekursiv abrufen

I eine Eigenschaft haben, Profundidade, dass calc rekursiv die Tiefe des Objekts. Eine weitere wichtige Eigenschaft ist Ordem. Es enthält die gewünschte Reihenfolge, die vom Benutzer in diesem Bereich definiert wurde.

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 

Schauen Sie sich diese Beispieltabelle an.

Ich versuche, eine Funktion ähnlich Profundidade zu erstellen, die seine globale Position berechnet. Ich versuche, die letzte Spalte OrdemGlobal zu bekommen. Dann kann ich Objekte von OrdemGlobal bestellen und es wird immer auf die gleiche Weise in jedem Lokal erscheinen, das ich brauche.

in dieser Tabelle Basierend, ist die korrekte Position

Root 
    +Users 
     +Administration 
     +Logs 
    +Customers 
     +Orders 

dass Verwaltung vor Logs Schauen apperars weil Verwaltung hat Ordem = 0 und Protokolle hat Ordem 1 =

Wie kann ich das gewünschte Verhalten archieve?

-Code meiner Klasse folgt

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: Verbesserte Frage

Ich habe versucht so etwas wie

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; 
    } 

Aber dieses ist verwirrt, und kehren nicht die gewünschte Information.

+0

Können Sie ein Beispiel dafür angeben, was GetGlobalOrder zurückgibt? –

Antwort

1

Hier ist ein IComparer<ModuloModel> sortiert nach der Reihenfolge, die Sie möchten.

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); 
     } 
    } 
} 

Hier ist ein Testprogramm, das es

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; 
    } 
} 

verwendet Hoffentlich genug ist, dass Sie auf dem richtigen Weg zu bekommen.

+0

Es funktionierte wie ein Zauber. Vielen Dank @Scott. –

0

Warum nicht einfach zurückgeben

return this.Ordem; 

Wo das Aggregat Wurzel? Die Klasse bezieht sich auf sich selbst, also muss sie wissen, welchen Ordemwert sie hat. Es weiß nichts darüber, nur Kinder.

Verwandte Themen