如何构建这个LINQ表达式?

时间:2012-11-07 18:17:39

标签: c# linq collections lambda

我有一个看起来像这样的课程:

class UserProfile { public int Id; public int? ParentId; public string Name; public string Role; }

每个UserProfile都是用户或管理员。每个用户可以是单个管理员的子女,其Id存储在用户的ParentId中。以下是一个例子:

IEnumerable<UserProfile> users = new List<UserProfile>{
        new UserProfile(){Id = 1, ParentId = null,  Name = "Admin1", Role = "Admin" },
        new UserProfile(){Id = 2, ParentId = 1,  Name = "User2", Role = "Admin" },
        new UserProfile(){Id = 3, ParentId = 1,  Name = "User3", Role = "Admin" },
        new UserProfile(){Id = 3, ParentId = null,  Name = "Admin2", Role = "Admin" },
        new UserProfile(){Id = 4, ParentId = 3,  Name = "User4", Role = "Admin" },
        new UserProfile(){Id = 5, ParentId = null,  Name = "User5", Role = "Admin" },
        new UserProfile(){Id = 6, ParentId = 3,  Name = "User6", Role = "Admin" },
    };  

我需要重新排列此列表或创建另一个列表,以便它按特定顺序排列: 所有管理员及其用户:

  • Admin1 (完整详情)
  • User2(完整详情)
  • User3(完整详情)
  • User5(完整详情)
  • Admin2 (完整详情)
  • User4(完整详情)
  • User6(完整详情)

我试图先将它们分开,但我不知道如何按所需顺序合并它们。

var adminsOnly = users.Where(p => p.Role.Equals("Admin")).OrderBy(p => p.Id);
var usersOnly = users.Where(p => p.Role.Equals("User")).OrderBy(p => p.Id);

非常感谢。

注意:可能有没有管理员的用户和没有用户的管理员。

3 个答案:

答案 0 :(得分:3)

var users = users.OrderBy(p => p.ParentId ?? p.Id).ThenBy(p => p.Role);

答案 1 :(得分:3)

试试这个:

users.Where(x => x.Role == "User" && x.ParentID == null)
     .Concat(users.Where(x => x.Role == "Admin")
                  .ToDictionary(x => x, 
                                x => users.Where(u => u.ParentId == x.Id));
                  .SelectMany(x => new[] {x.Key}.Concat(x.Value)));

这将为您提供IEnumerable<UserProfile>,其管理员列出所有用户,并且所有用户都没有先列出管理员。

答案 2 :(得分:0)

根据问题中的新信息,Istern的回答似乎最好。我看到的唯一缺点是没有管理员的用户将被他们的ID分类到列表中,不一定在开头或结尾。