Linq排序嵌套表

时间:2009-09-29 14:25:16

标签: c# linq linq-to-sql

跟进问题:

Linq Combine Left Join Data

说我有以下数据库表:

Users
-------
UserId (PK)
UserName

Roles
-----
RoleId (PK)
RoleName

UserRoles
---------
UserId (PK)
RoleId (PK)
Users 1-M UserRoles M-1 Roles

使用LinqToSQL,我可以返回以下内容(感谢上一个问题的回复):

[User1], [Role1, Role2, Role3]
[User2], [Role2, Role3] 
[User3], [Role3]

扭曲是我试图按角色排序。如何按角色对结果进行排序?

澄清

我有一个网格,当用户点击Roles列时,行将按该列排序。

所以启动网格看起来像这样:

[User1], [Role1, Role2, Role3]
[User2], [Role2, Role3] 
[User3], [Role3]

然后,如果他们对Roles列进行排序,它将看起来像这样

[User3], [Role3]
[User2], [Role2, Role3] 
[User1], [Role1, Role2, Role3]

4 个答案:

答案 0 :(得分:1)

只需稍微更改原始答案:

from u in dataContext.Users
select new { User = u, Roles = u.UserRoles.Select(ur => ur.Role)
                                          .OrderBy(r => r.RoleName) };

(假设你想要按照它所包含的角色对结果的每个元素进行排序。如果这不正确,请详细解释你想要的内容。)

答案 1 :(得分:0)

你能不能简单地使用这样的东西吗?

// users is the collection you already got from Linq2Sql
var usersSorted = from u in users order by u.Roles select u;

答案 2 :(得分:0)

int ascending = 1; //set to -1 for descending

from u in Users
orderby u.Roles.Count * ascending
select new { u, u.Roles.OrderBy(x => x.RoleName) }

您的查询需要满足多对多(未显示)。

答案 3 :(得分:0)

嘿@zzz,我到目前为止看到的答案似乎表明如何为每个用户排序行,而如果我理解你的澄清,你确实想要那个,但你要求的是如何然后按字母顺序排序这些语句。我会尽力回答这个问题。

虽然您的请求非常常见,但遗憾的是,SQL没有将表(Roles列)转换为逗号分隔字符串的本机方式。这通常不是问题,因为您可以简单地将角色字段作为

返回
{
    UserName = u.UserName,
    RolesList = string.Join(", ", 
        u.UserRoles.Select(ur => ur.Role.RoleName).ToArray())
}

令人惊讶的是,即使我刚刚提到SQL中没有与string.Join相同的函数,这也会有用。那是因为LINQ非常聪明,只需让SQL返回表并在最后一分钟在内存中应用string.Join()。

当您尝试按RoleList字段排序时会出现问题,因为它在内存中而不是在SQL中创建。如果您这样做,您将收到以下错误消息。

  

NotSupportedException:方法   'System.String Join(System.String,   System.String [])'不受支持   转换为SQL。

这为您提供了两种选择:

  1. 使用custom function to convert a table to a comma separated list编写存储过程以执行此操作。
  2. 或者将整个结果集返回到内存中,将其返回为.ToList(),然后执行排序ie(/ 我的整个查询 /)。ToList()。OrderBy(q => ; q.Roles);
  3. 如果您有大型数据集,第二个选项会慢得多。如果用户列表永远不会变得非常大,或者只有在管理员加载用户管理屏幕时才会不经常调用此查询,那么内存选项可能不会明显变慢;但是,如果经常调用此查询和/或用户表会变大,那么这可能不是一个可行的选择。

    我建议第三种选择。重新评估要求。在这种情况下,用户可能确实需要过滤功能,他们可以查看处于a,b,c角色的所有用户。如果这是真正的需要,那么排序不仅难以实施,而且可能也是一个更糟糕的解决方案。

    祝你好运!