我正在尝试将以下 SQL 行级安全函数转换为表格模型中的 DAX 过滤器
CREATE FUNCTION [Security].[fn_securitypredicate](@BrandID AS INT, @ChannelId AS INT)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(SELECT 1 AS fn_securitypredicate
WHERE (EXISTS ( SELECT 1 FROM security.RLSStaffBrand WHERE StaffUsername = SYSTEM_USER AND BrandId = @BrandID)
AND EXISTS ( SELECT 1 FROM security.RLSStaffChannel WHERE StaffUsername = SYSTEM_USER AND ChannelId = @ChannelID) )
OR ( EXISTS (SELECT 1 FROM security.RLSStaffBrand WHERE StaffUsername = SYSTEM_USER AND BrandId = @BrandID)
AND NOT EXISTS ( SELECT 1 FROM security.RLSStaffChannel WHERE StaffUsername = SYSTEM_USER ) )-- this user is not restricted by Channel
OR (NOT EXISTS ( SELECT 1 FROM security.RLSStaffBrand WHERE StaffUsername = SYSTEM_USER)
AND EXISTS ( SELECT 1 FROM security.RLSStaffChannel
WHERE StaffUsername = SYSTEM_USER AND ChannelId = @ChannelID) )
)
GO
到目前为止,我有以下 DAX 过滤器,但这只处理 SQL 代码中的第一个条件。我不知道是否有可能在 DAX 中复制其余部分。
='Brand'[BrandId]=LOOKUPVALUE('RLSStaffBrand'[BrandId], 'RLSStaffBrand'[StaffUsername], USERNAME(), 'RLSStaffBrand'[BrandId], 'Brand'[BrandId])
='Channel'[ChannelId]=LOOKUPVALUE('RLSStaffChannel'[ChannelId], 'RLSStaffChannel'[StaffUsername], USERNAME(), 'RLSStaffChannel'[ChannelId], 'Channel'[ChannelId])
不是您确切问题的答案,而是不是将 SQL 转换为 DAX 并将其维护在两个地方,您可以在 RLS 实现中重用 SQL 逻辑,以使用允许的 (Username,BrandId) 对在表格模型中具体化表,和允许的 (Username,ChannelId) 对枚举。
因此,编写一个视图并在您的表格模型中加载一个表,其中包含如下查询的结果:
这将枚举(BrandId、ChannelId、StaffUserName)的所有允许组合。然后通过在该表和品牌以及该表和频道之间设置双向交叉筛选,在您的 DAX 行筛选器中使用该新表。
大卫