【发布时间】:2011-02-01 18:29:42
【问题描述】:
我有一个安全架构,其中某些实体通过 SecureEntity 引用得到保护。 SecureEntity 有一个 RolePermissions 集合,每个 RolePermissions 都有一个 Allow 标志和一个 Priority。这个想法是将用户的角色与 SecureEntity 上的 RolePermissions 进行匹配。例如,用户可能被其最低优先级权限允许但被更高优先级权限拒绝,因此它是我们感兴趣的最高权限。在此示例中,我正在查询的根实体称为 ProcessCategory。
(SecureRoleId 是用户角色的匹配项;SecureRoleName 只是一个字符串描述。)
假设用户具有角色 (1,2) 并且 SecureEntity 具有 RolePermissions:
SecureRoleId = 1, Priority = 0, Allow = true
SecureRoleId = 2, Priority = 1, Allow = false
在这种情况下,不会选择实体。但如果用户只有角色 1,则将选择实体。当然,SecureEntity 可能包含一堆用户没有且不相关的其他角色。
下面的 sql 代码工作并执行此操作:“如果用户还拥有的最高优先级角色权限是 Allow=true,则选择实体”。因此,它基本上过滤用户自己的角色(IN 子句)的 RolePermission,按优先级排序,如果是 Allow,则采用最高的。
这是 Sql:
select pc.* from ProcessCategory pc
join SecureEntity se
join RolePermission rp on se.SecureEntityId = rp.SecureEntityId
on pc.SecureEntityId = se.SecureEntityId
where rp.RolePermissionId = (select top 1 RolePermissionId
from RolePermission
where Allow = 1
and SecureEntityId = se.SecureEntityId
and SecureRoleId in(0,1)
order by Priority desc)
上面的 Sql 可能有另一种写法,但它可以满足我的需要。理想情况下,我想使用 NHibernate Linq 或 Criteria 来实现这一点。我花了几个小时试图让 Linq 工作,但由于内部连接到 RolePermission 的各种“无效操作”异常而失败。我对 ICriteria 或 MultiCriteria 没有太多经验,如果有人可以帮助我,我会很感兴趣。
请注意,对象的 Fluent 映射很简单:
<some-entity>.References(x => x.SecureEntity)
和
SecureEntity.HasMany(x => x.RolePermissions).Not.Inverse();
【问题讨论】:
标签: nhibernate linq-to-nhibernate