2009-09-29 148 views
1

後續問題是:LINQ的排序嵌套表

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] 

扭曲是我想按Rol ES。我如何根據角色對結果進行排序?

澄清

我有一個網格,當用戶點擊角色列,行會按該列排序。

因此,要啓動電網是這樣的:

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

當然,如果他們那種對角色列它看起來像這樣

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

你能定義你想如何按角色排序嗎?這就是爲什麼LINQ不僅僅提供一個選項,因爲沒有明顯的方法。你是否想爲每個用戶按字母順序排列角色列表,然後轉換爲逗號分隔的字符串,然後讓所有用戶按該角色字符串排序? – 2009-09-29 14:30:30

+0

@拉米鴨,我已經提供了一個澄清。現在有道理嗎? – zzz 2009-09-29 14:48:23

回答

1

只要改變原來的答案非常輕微:

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

(這是假設你想排序每個元素由它包含的角色的結果。如果這不正確,請更詳細地解釋你想要的內容。)

+0

@Jon Skeet,我提供了一個澄清。現在有道理嗎? – zzz 2009-09-29 14:49:22

0

難道你不能簡單地使用這樣的東西嗎?

// users is the collection you already got from Linq2Sql 
var usersSorted = from u in users order by u.Roles select u; 
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) } 

您的查詢需要迎合多對多雖然(未顯示)。

0

嗨@zzz,迄今爲止我看到的答案似乎表明如何爲每個用戶排序行,而如果我理解您的說明,您確實需要這樣做,但您要求的是然後按字母順序排序這些語句。我會盡力爲這個問題提供一個答案。

雖然您的請求很常見,但遺憾的是,SQL沒有將表(Roles列)轉換爲以逗號分隔的字符串的原生方式。這通常是沒有問題的,因爲你可以簡單地返回角色字段

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

這將工作,奇怪的是,儘管我剛纔提到的,沒有相應的功能可以在的string.join SQL。這是因爲LINQ足夠聰明,只需讓SQL返回表並在最後一分鐘在內存中應用string.Join()即可。

問題出現在您嘗試按RoleList字段排序時,因爲它是在內存中創建的,而不是在SQL中創建的。如果你這樣做,你會得到以下錯誤信息。

NotSupportedException異常:方法 「System.String加入(System.String, 系統。String [])'不支持 轉換爲SQL。

這使你有兩個選擇:

  1. 編寫存儲過程可以做到這一點利用custom function to convert a table to a comma separated list。通過將整個結果集返回爲.ToList(),然後執行排序即,(/ 我的整個查詢 /).ToList().OrderBy(q=> q.Roles);

如果你有一個大的數據集,第二個選項會慢很多。如果用戶列表永遠不會變得非常大,或者只有當管理員加載用戶管理屏幕時纔會調用此查詢,那麼內存選項可能不會明顯變慢;然而,如果這個查詢將被頻繁地調用,並且/或者用戶表會變大,那麼這可能不是一個可行的選擇。

我會建議第三個選項。重新評估要求。在這種情況下,用戶可能確實需要過濾功能,以便他們可以查看處於a,b,c角色的所有用戶。如果這是真正的需求,那麼分類不僅難於實施,而且也可能是更糟糕的解決方案。

祝你好運!