2016-04-01 16 views
3

Dieser Titel ist nicht sehr gut, so prüfen Sie Folgendes. Ich habe fünf Tabellen:TSQL - Wählen Sie aus der Tabelle mit mehreren Join-Pfaden

Und ich möchte alle Berechtigungen für einen Benutzer bekommen, die ihn direkt verbunden sind oder indirekt über das Profil. Die nicht ganz da SQL ich mit so habe kommen weit ist dies:

SELECT [Pe].[Controller], 
     [Pe].[Action] 
FROM [PermissionSets] AS [PS] 
     JOIN [UserPermissionSets] AS [UPS] 
      ON ([UPS].[PermissionSetId] = [PS].[Id]) 
     JOIN [Users] AS [U] 
      ON ([U].[Id] = [UPS].[UserId]) 
     JOIN [Profiles] AS [P] 
      ON ([P].[Id] = [U].[ProfileId]) 
     JOIN [ProfilePermissionSets] AS [PPS] 
      ON ([PPS].[ProfileId] = [P].[Id]) 
     JOIN [Permissions] AS [Pe] 
      ON ([Pe].[PermissionSetId] = [PS].[Id]) 
WHERE [U].[Id] = 4; 

Es gibt eine richtige Anzahl von Zeilen zurück, aber es ist die Steuerung oder die Aktion immer und immer wieder zu wiederholen, so dass es falsch ist. Ich hoffe, dass jemand mir helfen kann, es zu korrigieren, um alle eindeutigen Berechtigungssätze für den Benutzer zu zeigen. Idealerweise würde ich es auch so ändern, dass es beim Benutzer entdeckt wird, weil ich dazu in der Methode Zugriff habe (das Objekt ist eine Entity Framework-Klasse mit dem Namen User und wird mit Browsed verwendet LINQ).

AKTUALISIERT, weil ich vergessen, dass ich wirklich die Berechtigung, um die Berechtigungssätze wollten.

+0

Suchen Sie einfach nach 'GROUP BY'? – ZLK

+0

Nicht sicher, ich kenne genug SQL, um Probleme für mich selbst zu verursachen, lol. – Gup3rSuR4c

+0

Hat ein Benutzer immer mindestens einen Eintrag in der Tabelle _UserPermissionSets_? Wenn nicht, werden nur Benutzer mit einem Eintrag in _UserPermissionSets_ oder in _UserPermissionSets_ und _Permissions_ abgerufen. Sie sollten dann 'LEFT OUTER JOIN' verwenden. – schlonzo

Antwort

1

Versuchen Sie, diese SQL

SELECT [Pe].[Controller], 
     [Pe].[Action] 
FROM [Users] AS [U] 
    LEFT OUTER JOIN [UserPermissionSets] AS [UPS] 
      ON ([UPS].[UserId] = [U].[Id]) 
    LEFT OUTER JOIN [ProfilePermissionSets] AS [PPS] 
      ON ([PPS].[ProfileId] = [U].[ProfileId]) 
    LEFT OUTER JOIN [Permissions] AS [Pe] 
      ON ([Pe].[PermissionSetId] = [UPS].[PermissionSetId]) 
      OR ([Pe].[PermissionSetId] = [PPS].[PermissionSetId]) 
WHERE [U].[Id] = 4; 
+0

Das erzeugt nur die direkt verwandten Berechtigungen und schließt die indirekt damit verbundenen Berechtigungen aus dem Profil. – Gup3rSuR4c

+0

@ Gup3rSuR4c, Abfrage geändert, PLZ Chk jetzt –

+0

Ich verfeinert Ihr Beispiel zu 'DISTINCT' und es gab mir die Ergebnisse, die ich wollte. Ich machte es dann zu einer Ansicht und machte eine gefälschte Beziehung aus der Klasse "Benutzer" in der EF-Implementierung. Funktioniert gut und reduziert die Abfragen auf nur eine vs meine LINQ-Implementierung. Vielen Dank! – Gup3rSuR4c

0

auf LINQPad So rumgespielt, kam ich so weit oben mit diesem als die Abfrage LINQ:

user.PermissionSets.Union(user.Profile.PermissionSets).SelectMany(
    ps => 
     ps.Permissions.Select(
      p => 
       p.Controller + "." + p.Action)); 

Und es produziert, was ich will, aber es funktioniert es durch das Zusammenstellen der Ergebnisse einer Reihe von SQL-Abfragen. Die größte Auswirkung kommt von Profilen, die mehrere Berechtigungssätze haben, wie der Administrator sagt. Ich glaube nicht, dass es einen Weg gibt, und ich habe nur ein User Objekt, mit dem ich arbeiten kann, also bin ich ok mit den übermäßigen SQL-Abfragen, zumindest für den Moment.

Verwandte Themen