首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Linq中的层次化

Linq中的层次化
EN

Stack Overflow用户
提问于 2010-06-23 12:40:01
回答 4查看 213关注 0票数 1

如果我有一组与以下类似的雇员数据:

代码语言:javascript
运行
复制
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添加分层层,即:

  • 首席执行官=1 (top)
  • CIO =2(2级)
  • XDIR和YDIR =3(Etc)
  • AMNGR=4(Etc)

H 110ASUP=5(Etc)H 211F 212

我已经能够根据SupervisorId对员工进行分组,但不确定如何实现“级别”。

代码语言:javascript
运行
复制
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);
  }

非常感谢。

EN

回答 4

Stack Overflow用户

发布于 2010-06-23 12:59:21

我会给你的linq“用户对象”添加一个排名。

代码语言:javascript
运行
复制
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,你会添加一个连接。

代码语言:javascript
运行
复制
     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
EN

Stack Overflow用户

发布于 2010-06-23 13:09:27

更新

以下是为每个级别创建查找表的一种方法。这是公平的,我不知道它将如何扩大。显然,您需要对其进行调整,以便从数据库中提取行。

定义一个类来保存我们的查找表

代码语言:javascript
运行
复制
public class user{
    public string SupervisorId;
    public string UserId;   
    public int Level;
}

然后,我们得到一个用户and /SupervisorId组合的唯一列表,然后循环遍历列表,通过“遍历”树来计算每个组合的级别。

代码语言:javascript
运行
复制
    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;             
        }

现在,您可以使用uniqueuser作为查找表来确定查询的级别。例如

代码语言:javascript
运行
复制
private int GetLevel(string userId){         
     return uniqueusers.Where(c => c.UserId == userId).FirstOrDefault().Level;    
  }

您甚至可以将其结合到一个步骤中,只需付出一点点努力。

票数 0
EN

Stack Overflow用户

发布于 2010-06-23 13:26:47

代码语言:javascript
运行
复制
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");

免责声明:

CEOs.

  • Preserves

  • 不处理背后的多个循环relationships.
  • Leaves孤儿。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3101642

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档