TSQL - 从具有多个连接路径的表中选择

时间:2016-04-01 04:58:06

标签: c# sql-server entity-framework linq tsql

这个标题不是很好,所以请考虑以下内容。我有五张桌子:

User {
    Id,
    ProfileId        // -> Profiles.Id
}

Profile {
    Id
}

ProfilePermissionSets {
    ProfileId        // -> Profiles.Id
    PermissionSetId  // -> PermissionSets.Id
}

UserPermissionSets {
    UserId           // -> Users.Id
    PermissionSetId  // -> PermissionSets.Id
}

PermissionSets {
    Id
}

Permissions {
    Id,
    PermissionSetId  // -> PermissionSets.Id
}

我希望获得直接链接到用户或通过配置文件间接链接的用户的所有权限。到目前为止,我提出的不太合适的SQL是:

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;

它返回正确的行数,但它反复重复控制器或动作,所以这是错误的。我希望有人可以帮我纠正它,以显示用户的所有不同权限集。理想情况下,我还要更改它,以便从用户开始发现它,因为这是我在需要执行此操作的方法中访问的对象(对象是名为User的实体框架类,并且将使用LINQ浏览。

更新因为我忘了我真的想要权限而不是权限集。

2 个答案:

答案 0 :(得分:1)

试试这个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;

答案 1 :(得分:0)

所以,在LINQPad上乱搞,我想到LINQ查询:

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

它产生了我想要的东西,但它是通过组合一堆SQL查询的结果来实现的。最大的影响来自具有多个权限集的配置文件,例如管理员。我认为没有办法绕过它,我只有一个User对象可以使用,所以我对多余的SQL查询没问题,至少目前是这样。