2016-11-10 96 views
1

我有一個自引用的類。 IdModuloPai是指向其父項的關鍵,ModulosFilhos是該對象的子項。C#獲取對象的位置遞歸

我有一個屬性,Profundidade,遞歸計算該對象的深度。

另一個重要的屬性是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訂購對象,並且它在每個我需要的地方都會以相同的方式出現。基於此表

,正確位置是

Root 
    +Users 
     +Administration 
     +Logs 
    +Customers 
     +Orders 

看,因爲政府有ORDEM = 0和日誌具有ORDEM = 1

我怎樣才能archieve所期望的行爲記錄在此之前,政府apperars?我班的

代碼如下

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

編輯:改進問題

我tryed像

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; 

哪裏聚合根?這個班級是指自己,所以它必須知道Ordem的價值。它不知道任何高於它的東西,只有它是兒童。