我有一个安全模式,某些实体通过SecureEntity引用进行安全保护。 SecureEntity具有一组RolePermissions,每个RolePermissions都有一个允许标志和一个优先级。这个想法是将用户的角色与SecureEntity上的RolePermissions进行匹配。例如,用户可能被其最低优先级权限所允许,但被较高权限所拒绝,因此它是我们感兴趣的最高权限。在此示例中,我查询的根实体称为ProcessCategory。将这个Sql查询翻译成NHibernate Linq或Criteria?
(SecureRoleId是匹配用户的角色; SecureRoleName只是一个字符串描述。)
假设一个用户角色(1,2)和SecureEntity有RolePermissions:
SecureRoleId = 1, Priority = 0, Allow = true
SecureRoleId = 2, Priority = 1, Allow = false
在这种情况下,实体将不会被选中。但是,如果用户只有角色1,则会选择该实体。当然,SecureEntity可能包含一些用户没有且无关紧要的其他角色。
下面的sql代码的工作原理是:'如果用户拥有的最高优先级角色权限Allow = true,则选择该实体。所以它基本上将RolePermission过滤到用户自己的角色(IN子句)上,按优先级进行排序,如果这是允许,则将其作为最高级别。
这里是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的经验,如果有人能帮助我,我会感兴趣。
注意,对于对象流利映射是直接的:
<some-entity>.References(x => x.SecureEntity)
和
SecureEntity.HasMany(x => x.RolePermissions).Not.Inverse();