2010-06-23 75 views
1

如果我有一組類似的員工數據:分級分層Linq中

var users = new[] 
{ 
    new {SupervisorId = "CEO", UserId = "CEO", UserName = "Joe"}, 
    new {SupervisorId = "CEO", UserId = "CIO", UserName = "Mary"}, 
    new {SupervisorId = "CIO", UserId = "XDIR", UserName = "Ed"}, 
    new {SupervisorId = "CIO", UserId = "YDIR", UserName = "Lisa"}, 
    new {SupervisorId = "XDIR", UserId = "AMNGR", UserName = "Steve"}, 
    new {SupervisorId = "AMNGR", UserId = "ASUP", UserName = "Lesley"} 
}; 

是否可以使用Linq添加分級層,在這個意義上說:

  • CEO = 1(頂部)
  • CIO = 2(第二級)
  • XDIR和YDIR = 3(第三級)
  • AMNGR = 4(等)
  • ASUP = 5(等)

我已經能集團員工根據SupervisorId,但不知道如何使「水平」發生。

var userGroups = from user in users 
    group user by user.SupervisorId into userGroup 
    select new 
    { 
    SupervisorId = userGroup.Key, 
    Level = ?????? 
    Users = userGroup.ToList() 
    }; 

    foreach (var group in userGroups) 
    { 
    Console.WriteLine("{0} - {1} - {2}", group.SupervisorId, group.Level, group.Users.Count); 
    } 

非常感謝。

+0

您是否希望級別適用於組中的所有成員。如果你看看集團首席執行官,那麼有2個級別。 – 2010-06-23 12:50:01

+0

@Leom,CEO supervisorid是多餘的,首席執行官監督=首席執行官。所以這個想法是,在SupervisorId = UserId的情況下,你是首席執行官 - 樹從那裏開始。 – dizzyguy 2010-06-23 16:23:52

回答

0

我想補充的排名到您的LINQ「用戶對象」

public class User{ 

    public string SupervisorId {get;set;} 
    public string UserId {get;set;} 
    public string UserName {get;set;} 
    public int Level {get { return GetRank(SupervisorId ) ; } } 

    private int GetRank(string userId){ 
    if(string.IsNullOrEmpty(userId)){ 
     //Bad case, probably want to use a very large number 
     return -1; 
    } 
    int level = 0; 
    switch(userId){ 
     case "CEO": 
      level = 0; 
      break; 

     //insert others here 

    } 

    } 
} 

那麼你的Linq您將添加一個連接。

 var userGroups = from user in users 
        join super in users on user.SupervisorId equals super.UserId 
        group user by user.SupervisorId into userGroup 
        select new 
    { 
     SupervisorId = userGroup.Key, 
     Level = super.Level, 
     Users = userGroup.ToList() 
    }; 
0

更新

繼承人之一,創建一個查找表爲每個級別的方式。它相當,我不知道它會如何擴大。顯然,您需要調整它以從數據庫中提取行。

定義一個類來保存我們的查找表

public class user{ 
    public string SupervisorId; 
    public string UserId; 
    public int Level; 
} 

然後我們得到用戶名/ SupervisorId組合和循環的唯一列表通過列表計算每個組合的水平通過「走」了樹。

var uniqueusers = (new user[] 
     { 
      new user {SupervisorId = "CEO", UserId = "CEO"}, 
      new user {SupervisorId = "CEO", UserId = "CIO"}, 
      new user {SupervisorId = "CIO", UserId = "XDIR"}, 
      new user {SupervisorId = "CIO", UserId = "YDIR"}, 
      new user {SupervisorId = "XDIR", UserId = "AMNGR"}, 
      new user {SupervisorId = "AMNGR", UserId = "ASUP"} 
     }).Distinct(); 


     foreach (var item in uniqueusers) 
     {   
      int level = 0; 
      user CurrentUser = item; 
      while (CurrentUser.UserId != CurrentUser.SupervisorId){ 
       CurrentUser = uniqueusers.Where(c => c.UserId == CurrentUser.SupervisorId).FirstOrDefault(); 
       level++; 
      } 
      item.Level = level;    
     } 

現在,您可以使用uniqueusers作爲查找表來確定查詢的級別。例如:

private int GetLevel(string userId){   
    return uniqueusers.Where(c => c.UserId == userId).FirstOrDefault().Level;  
    } 

你甚至可以用一點努力將它結合成一個單一的步驟。

+0

與上述相同的問題...結果實際上來自數據庫,我無法對任何類型的分層進行硬編碼。該代碼需要能夠基於以下想法來推斷該級別: 1)CEO是頂級節點,其中supervisorID - userID和 2)下面的每個圖層都由supervisorID定義,例如,如果您的主管是首席執行官,那麼你是第2級,等等...... – dizzyguy 2010-06-23 16:30:39

+0

如果你的主管是首席執行官,你的用戶是首席執行官,那麼你是首席執行官,讓我糾正第二條陳述。但如上所述,它適用於下面的每個級別。 – dizzyguy 2010-06-23 16:31:46

+0

這看起來非常有前途!我今天會試一試。謝謝! – dizzyguy 2010-06-25 13:29:14

0
ILookup<string, User> subordLookup = users 
    .ToLookup(u => u.SupervisorId); 

foreach(User user in users) 
{ 
    user.Subordinates = subordLookup[user.UserId].ToList(); 
} 

User userHierarchy = user.Single(u => u.UserId == "CEO"); 

免責聲明:

  • 不處理多個老總。
  • 保留循環關係。
  • 遺落的孤兒。
+0

我目前沒有定義用戶類型。你可以解釋一下我將如何去實現它? – dizzyguy 2010-06-23 16:27:04

+0

我將嘗試將User作爲一個具有上面定義的特性的新類來實現,看看它是否有效。 – dizzyguy 2010-06-23 16:34:00

0

這是你在找什麼?

  var levels = new[] 
     { 
      new { Level = 1, LevelName = "CEO" }, 
      new { Level = 2, LevelName = "CIO" }, 
      new { Level = 3, LevelName = "XDIR" }, 
      new { Level = 3, LevelName = "YDIR" }, 
      new { Level = 4, LevelName = "AMNGR" }, 
      new { Level = 5, LevelName = "ASUP" } 
     };       

     var userGroups = from user in users 
         join level in levels on 
         user.UserId equals level.LevelName        
         group new{ User = user, Level = level.Level } by new { SuperId = user.SupervisorId, Level = level.Level } into userGroup 
         select new 
          { 
           SupervisorId = userGroup.Key.SuperId, 
           Level = userGroup.Key.Level, 
           Users = userGroup.ToList() 
          }; 
+0

問題是我正在從數據庫中檢索這個值。對象用戶的代碼只是一個例子。我的數據庫只包含用戶標識和管理員標識,我需要能夠根據這個標準來更新層次結構 - 以CEO爲根。 – dizzyguy 2010-06-23 16:28:25