2014-01-30 79 views
0

我有以下3(簡化)模型類,其中每個都包含了其他的集合:獲取從另一個列表和屬性列表結果

Group.CollectionOfPermissions 
Group.CollectionOfUsers 
User.CollectionOfGroups 
User.CollectionOfPermissions 
Permission.CollectionOfGroups 
Permission.CollectionOfUsers 

我有一個基於關景色的單個User.ID,我希望能夠返回所述用戶的有效權限。

的有效權限基於關:

  1. 各個用戶的權限,這是簡單地將User.CollectionOfPermissions屬性。
  2. 用戶所屬組的派生權限。也就是說,對於用戶所屬的每個組,我都需要獲取這些權限。

數字1顯然和引用collection屬性一樣簡單。 2號是我在LINQ選擇方面遇到更多麻煩的地方。

我可以寫的線沿線的一個存儲過程:

SELECT * FROM PERMISSIONS P WHERE P.ID IN 
(SELECT PERMISSION_ID FROM PERMISSION_GROUP_REF PGR WHERE PGR.GROUP_ID IN 
(SELECT ID FROM GROUPS G WHERE G.ID IN 
(SELECT GROUP_ID FROM GROUP_USER_REF GUR WHERE GUR.USER_ID IN 
(SELECT ID FROM USERS U WHERE U.ID = @USERID)))) 

但我寧願與項目的其餘部分要記住這行,並繼續使用LINQ,尤其是因爲我想避免直接在代碼中查詢引用表(假設集合已經作爲類屬性存在)。我將如何處理這種LINQ查詢?

編輯:這是使用實體框架6剃刀3

+0

您使用的是什麼o/rm技術?實體框架?什麼版本? –

+0

@IainGalloway將詳細編輯,很好的電話! – TheQ

回答

2
Users.Where(u => u.UserId == userId) 
    .SelectMany(u => u.CollectionOfPermissions) 
    .Select (cp=>cp.Permission) // you might need to do this too 
    .Union(Users.Where(u => u.UserId == userId) 
       .SelectMany(u => u.CollectionOfGroups) 
       .SelectMany(cg => cg.Permission)) 

可能是這樣的。

編輯:作爲參考,這將產生以下SQL(稍有不同的列名在我的測試臺): -

SELECT 
[Distinct1].[C1] AS [C1] 
FROM (SELECT DISTINCT 
    [UnionAll1].[Permission_Id] AS [C1] 
    FROM (SELECT 
     [Extent1].[Permission_Id] AS [Permission_Id] 
     FROM [dbo].[PermissionPersons] AS [Extent1] 
     WHERE 1 = [Extent1].[Person_Id] 
    UNION ALL 
     SELECT 
     [Extent3].[Permission_Id] AS [Permission_Id] 
     FROM [dbo].[PersonGroups] AS [Extent2] 
     INNER JOIN [dbo].[PermissionGroups] AS [Extent3] ON [Extent2].[Group_Id] = [Extent3].[Group_Id] 
     WHERE 1 = [Extent2].[Person_Id]) AS [UnionAll1] 
) AS [Distinct1] 

在又一想,爲什麼不通過Permission實體查詢所有在一起嗎?

context.Permissions.Where(p=> 
          p.Groups.Any(gr=>gr.Users.Any(u=>u.UserId == userId)) 
          || p.Users.Any(u=>u.UserId == userId)) 
        .Distinct() 
+0

整理了一下格式,所以我可以讀它,希望你不介意。我懷疑第二個最後的擴展方法調用需要也是「SelectMany」 –

+0

謝謝,我認爲你是對的:) –

+0

我認爲我的需要,我可以擺脫LINQ查詢的第三行,但我需要多測試一下。這看起來是正確的道路,但稍後我會再次更新時會再更新一次。感謝您向正確方向邁出的第一步,我希望! – TheQ

0

您發佈的SQL翻譯成這樣:

PERMISSIONS.Where(p => 
    PERMISSION_GROUP_REF.Where(pg => 
    GROUPS.Where(g => 
     GROUP_USER_REF.Where(gu => gu.USER_ID == USERID) 
        .Any(gu => gu.GROUP_ID == g.ID)) 
      .Any(g => g.ID == pg.GROUP_ID)) 
     .Any(pg => pg.PERMISSION_ID == p.ID)) 

也許你可以把它簡化一下,但這應該工作。

+0

整理了一下格式,所以我可以讀它,希望你不介意 –

+0

我編輯它的原始問題,但我應該指定之前:我使用實體框架6,所以實際上並不存在參考對象的類/模型(PERMISSION_GROUP_REF和GROUP_USER_REF)。 – TheQ

相關問題