C# LINQ展平循环参考

C# LINQ展平循环参考,c#,linq,C#,Linq,我有一个用户对象: class user { int userId {get; set;} string name {get; set} int supervisorId {get; set} } 每个supervisorId也是users表中的一个useId。我试图找到一种合理的方法来建立一个用户主管的层次结构,一直到最高层。因此,选择一个用户的supervisorID,然后选择那个用户的supervisorID,等等。我现在正在处理一个越来越难看的for循环,但希望有人有一些更

我有一个用户对象:

class user
{
  int userId {get; set;}
  string name {get; set}
  int supervisorId {get; set}
}

每个supervisorId也是users表中的一个useId。我试图找到一种合理的方法来建立一个用户主管的层次结构,一直到最高层。因此,选择一个用户的supervisorID,然后选择那个用户的supervisorID,等等。我现在正在处理一个越来越难看的for循环,但希望有人有一些更优雅的东西。

你只是想找到一种方法来确定某个特定用户是否是最优秀的人吗?一个空的监管者不就说明了这一点吗

您可以使SupervisorId为空

int? supervisorId


在你最初的文章中,我以类为基础,总结了一个小例子,说明了如何使用递归方法在用户列表(或任何你拥有的可枚举项)中向上移动,直到找到主管。我确实假设高层的主管有一个设置好的主管id来将他们标识为高层。为了能够显示这一点,我现在将0放入其中

有两个示例,一个仅返回主管,另一个返回整个层次结构

public class Program  {

private const int SupervisorId = 0;

static void Main(string[] args)
{
  List<user> users = new List<user>();
  users.Add(new user {userId = 1, name = "1", supervisorId = SupervisorId});
  users.Add(new user { userId = 2, name = "2", supervisorId = SupervisorId});
  users.Add(new user { userId = 3, name = "3", supervisorId = 1 });
  users.Add(new user { userId = 4, name = "4", supervisorId = 1 });
  users.Add(new user { userId = 5, name = "5", supervisorId = 2 });
  users.Add(new user { userId = 6, name = "6", supervisorId = 5 });

  var nonSupervisors = users.Where(u => u.supervisorId != SupervisorId);
  Dictionary<user, user> userAndSupervisor = nonSupervisors.ToDictionary(user => user, user => FindSupervisor(users, user));
  Dictionary<user, List<user>> userAndHierarchy =nonSupervisors.ToDictionary(user => user, user => FindSupervisorHierarchy(users, user));
}

static user FindSupervisor(List<user> users, user user)
{
  var parentUser = users.FirstOrDefault(u => u.userId == user.supervisorId);
  if (parentUser?.supervisorId != SupervisorId)
  {
    parentUser = FindSupervisor(users, parentUser);
  }
  return parentUser;
}

static List<user> FindSupervisorHierarchy(List<user> users, user user)
{
  var parentUsers = users.Where(u => u.userId == user.supervisorId);
  if (parentUsers.All(x => x.supervisorId != SupervisorId))
  {
    parentUsers = parentUsers.Concat(FindSupervisorHierarchy(users, parentUsers.FirstOrDefault()));
  }
  return parentUsers.ToList();
}
}
公共类程序{
private const int SupervisorId=0;
静态void Main(字符串[]参数)
{
列表用户=新列表();
添加(新用户{userId=1,name=“1”,supervisorId=supervisorId});
添加(新用户{userId=2,name=“2”,supervisorId=supervisorId});
添加(新用户{userId=3,name=“3”,supervisorId=1});
添加(新用户{userId=4,name=“4”,supervisorId=1});
添加(新用户{userId=5,name=“5”,supervisorId=2});
添加(新用户{userId=6,name=“6”,supervisorId=5});
var非监督者=用户。其中(u=>u.supervisorId!=supervisorId);
Dictionary userAndSupervisor=nonSupervisors.ToDictionary(用户=>user,用户=>FindSupervisor(用户,用户));
字典userAndHierarchy=nonsupervisiors.ToDictionary(用户=>user,用户=>findsupervisiorhierarchy(用户,用户));
}
静态用户FindSupervisor(列出用户、用户用户)
{
var parentUser=users.FirstOrDefault(u=>u.userId==user.supervisorId);
if(parentUser?.supervisorId!=supervisorId)
{
parentUser=FindSupervisor(用户,parentUser);
}
返回父用户;
}
静态列表查找SupervisorHierarchy(列表用户、用户用户)
{
var parentUsers=users.Where(u=>u.userId==user.supervisorId);
if(parentUsers.All(x=>x.supervisorId!=supervisorId))
{
parentUsers=parentUsers.Concat(FindSupervisorHierarchy(users,parentUsers.FirstOrDefault());
}
返回parentUsers.ToList();
}
}

首先让您的用户对象不那么可怕:

class User
{
  public int Id {get; private set;}
  public string Name {get; private set;}
  private int supervisorId;
  public User Supervisor 
  {
    get { ... implement it ... } 
  }
对于没有管理员的用户,让
Supervisor
返回
null

现在,您可以实现:

  public IEnumerable<User> ManagementChain()
  {
    User current = this.Supervisor;
    while(current != null) 
    {
      yield return current;
      current = current.Supervisor;
    }
  }
}
public IEnumerable ManagementChain()
{
用户当前=此.Supervisor;
while(当前!=null)
{
产生回流电流;
当前=当前。主管;
}
}
}

你完成了;现在,您有了一系列适用于任何用户的监控器。排名靠前的用户有一个空的主管序列。

请显示您的“不雅”代码(并非所有语言都有优雅的解决方案)。这里没有问题,只有您想要的东西列表。你的问题是什么?“linq展平循环引用”这个标题与您的问题有什么关系?正文中没有提到linq、扁平化或循环引用。没有主管的人的主管ID是什么?首席执行官,我有代码在该级别停止。我不知道在这种情况下“构建层次结构”是什么意思。您已经有了层次结构。我猜您需要一个算法来遍历层次结构,以获得特定的结果或结果集。您需要什么输出?不,我正在尝试创建一个管理者的层次结构。所以我传入一个用户ID,获取他们的主管,然后是主管的主管,等等。那么为什么不使用这个循环,将ID添加到
列表中,然后完成它呢?这让我非常接近。实际上,我只需要基于一个人构建层次结构。所以基于用户,然后是他们的老板,然后是他们的老板。我想我能从这得到。非常感谢。“FindSupervisorHierarchy”方法应该为您完成这项工作。不客气。我们的模型已经这样设置好了,现在,我正在填充Supervisor子对象。我正在尝试实施管理链方法,但它只是让第一个主管回来。我应该在用户对象上使用ManagementChain,还是在填充用户对象的服务中使用ManagementChain?
  public IEnumerable<User> ManagementChain()
  {
    User current = this.Supervisor;
    while(current != null) 
    {
      yield return current;
      current = current.Supervisor;
    }
  }
}