我有以下3个(简化的)模型类,每个类都包含另一个的集合:
Group.CollectionOfPermissions
Group.CollectionOfUsers
User.CollectionOfGroups
User.CollectionOfPermissions
Permission.CollectionOfGroups
Permission.CollectionOfUsers
我有一个基于单个User.ID的View,我希望能够为所述用户返回有效权限。
有效权限基于:
数字1显然与引用集合属性一样简单。 数字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和Razor 3
答案 0 :(得分: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()
答案 1 :(得分: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))
也许你可以稍微简化它,但这应该有效。