我想在一个视图中转换这个查询,我可以调用传递 UserId 作为参数来选择与该用户相关的所有组(包括这些组的子树)。
事实上,我有 2 张桌子:
- “EVA_Roles”包含角色树,通过 RoleHid 字段中的物化路径定义为 varchar(8000)
- "EVA_UsersInRoles" 通过字段 UserId 将用户与角色相关联
这里的问题是只有一些角色可能与 EVA_UsersInRoles 表中的用户相关,但也许这些角色是树层次结构中其他角色的父级,因此我必须为每个用户检索多个子树。最后我想出了这个似乎工作正常的查询,但我想在视图中转换它。当然,我面临的问题是 UserId 参数(我将用于过滤视图结果的参数)位于子查询中。
任何将其重构为视图的提示?
SELECT A.RoleId, E.EndDate FROM EVA_Roles A INNER JOIN EVA_Roles B ON
A.RoleHid LIKE B.RoleHid + '%' AND B.RoleHid IN (SELECT RoleHid FROM EVA_Roles C
LEFT JOIN EVA_UsersInRoles D ON C.RoleId = D.RoleId WHERE
(D.Userid = @0 OR C.RoleId = @1) AND C.ApplicationId = @2)
LEFT JOIN EVA_UsersInRoles E ON A.RoleId = E.RoleId AND E.UserId = @0 WHERE
A.ApplicationId = @2 ORDER BY A.RoleId
我在应该将值传递给视图的地方留下了参数。我认为在一个视图中重构可能是不可能的。这只是以更友好的方式利用我的微 ORM(PetaPoco),否则我必须在我的代码中使用 SQL 但没关系,不要在这方面失去理智。
关于表定义:
EVA_Roles
RoleId INT - Primary Key
RoleHid VARCHAR(800) - Here I store the materialized path of the tree using nodes
ids... An example on this later.
RoleLevel INT - Security level of the role
RoleName INT - Name of the role (admin, guest, ...)
ApplicationID INT - Id of the application (in a multi app scenario)
EVA_UsersInRoles
RoleId - INT
UserId - INT
RoleHid 中的物化路径遵循此逻辑。考虑以下数据,其中 RoleId 2 是 RoleId 1 的子项:
RoleId 1
RoleHid “1”。
RoleId 2
角色隐藏“1.2”。
通过上面的查询,我可以检索与特定用户和应用程序相关的所有子树。