【发布时间】:2021-11-27 14:48:15
【问题描述】:
考虑以下数据模型:
- 一个委托人有多个角色(多对多);
- 角色授予多个权限(多对多);
现在我想使用 LINQ 来确定 Principal 是否具有权限,即他是否在任何拥有此权限的角色中。
对于这种情况,通常我会在连接表上使用AnyAsync,但由于我要遍历多个连接表,所以我真的很挣扎。我最初想出了这个:
var query = context.Principals
.Where(p => p.Id == "SomeUUID")
.Include(p => p.Roles)
.ThenInclude(r => r.Permissions
.Where(p => p.Name == "SomePermission"));
但现在我必须再次通过 Principal 遍历(可能在内存中)附加的角色以搜索 Any 权限。
有没有办法可以在同一个查询中顺利应用此检查?
编辑:这是生成的 SQL 以补充 Parks 的(底部)答案:
SELECT CASE
WHEN EXISTS (
SELECT 1
FROM [Principals] AS [a]
INNER JOIN (
SELECT [a1].[Id], [a1].[Description], [a1].[DisplayName], [a0].[RoleId], [a0].[PrincipalId]
FROM [PrincipalRoles] AS [a0]
INNER JOIN [Roles] AS [a1] ON [a0].[RoleId] = [a1].[Id]
) AS [t] ON [a].[PrincipalId] = [t].[PrincipalId]
INNER JOIN (
SELECT [a3].[Id], [a3].[Name], [a2].[RoleId], [a2].[PermissionId]
FROM [RolePermissions] AS [a2]
INNER JOIN [Permissions] AS [a3] ON [a2].[PermissionId] = [a3].[Id]
) AS [t0] ON [t].[Id] = [t0].[RoleId]
WHERE ([a].[PrincipalId] = "SomePrincipal") AND ([t0].[Name] = "SomePermission")) THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END
SELECT CASE
WHEN EXISTS (
SELECT 1
FROM [Principals] AS [a]
WHERE ([a].[PrincipalId] = "SomePrincipal") AND EXISTS (
SELECT 1
FROM [PrincipalRoles] AS [a0]
INNER JOIN [Roles] AS [a1] ON [a0].[RoleId] = [a1].[Id]
WHERE ([a].[PrincipalId] = [a0].[PrincipalId]) AND EXISTS (
SELECT 1
FROM [RolePermissions] AS [a2]
INNER JOIN [Permissions] AS [a3] ON [a2].[PermissionId] = [a3].[Id]
WHERE ([a1].[Id] = [a2].[RoleId]) AND ([a3].[Name] = "SomePermission")))) THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END
【问题讨论】:
标签: entity-framework linq .net-core entity-framework-core