Измерение DAX не работает при включении RLS — ожидается, что пути соединения образуют дерево

#powerbi #dax #powerbi-desktop

#powerbi #dax #powerbi-desktop

Вопрос:

В Power BI у меня есть следующая ошибка для измерения при включении RLS (эта ошибка не отображается, когда RLS выключен):

 Join paths are expected to form a tree but the table has two join paths
 

введите описание изображения здесь

Это соответствующие взаимосвязи в модели:

введите описание изображения здесь

У меня неактивные отношения. Эта неактивная связь используется в мере решения проблемы. Но поскольку он неактивен, я бы подумал, что это не будет проблемой?? Мера:

 TTipsInvs =
VAR SalesValue =
    CALCULATE (
        SUM ( ANSAPBICustomerTransDetailed[Outstanding] ),
        USERELATIONSHIP ( 'ANSAPBICustomerTransDetailed'[SiteID], ANSAPBISites[Site ID] )
    )
RETURN
    IF ( ISBLANK ( SalesValue ), 0, ( SalesValue ) )
 

Есть ли способ избежать этой проблемы при включении RLS?

Приветствую всех за помощь

Комментарии:

1. Вам действительно нужны эти отношения? почему бы не использовать таблицу мостов, CustomerandAgent ?

2. Мне нужно суммировать ANSAPBICustomerTransDetailed[Выдающийся] с помощью ANSAPBISite[SiteID], таблица ANSAPBICustomerTransDetailed содержит столбец SiteID, а CustomerAndAgent — нет. Есть ли какая-либо другая функция в DAX, которую я мог бы использовать, которая позволила бы мне использовать активные отношения, но группировать по сайтам. SiteID?

3. Тогда почему вы подключаете сайт к Customerandagent, если в нем нет сайта? Похоже, вам нужно изменить свою модель, чтобы правильно отразить вашу бизнес-логику

4. Мне также нужно сообщать о сайтах по клиентам в том же отчете. Клиент может владеть одним / многими сайтами, у клиента может быть одна / много пользовательских транзакций. Мне нужно сообщать о транзакциях клиентов как по сайтам, так и по клиентам, и мне также нужно сообщать о сайтах по клиентам. Надеюсь, это имеет смысл? Это боль, но это то, что есть.

Ответ №1:

 TTipsInvs =
VAR SiteID =
    CALCULATETABLE (
        VALUES ( ANSAPBISites[Site ID] ) )
VAR SalesValue =
    CALCULATE (
        SUM ( ANSAPBICustomerTransDetailed[Outstanding] ),
        TREATAS ( SiteID, 'ANSAPBICustomerTransDetailed'[SiteID] ) )
RETURN
    IF ( ISBLANK ( SalesValue ), 0, ( SalesValue ) )
 

Комментарии:

1. Можете ли вы объяснить, как это работает и почему USERELATIONSHIP() не работает с RLS? Связано ли это с тем, как применяется контекст? Этот ответ также решил мои проблемы, но мне хотелось бы получить более глубокое объяснение того, что происходит.

2. Моя интерпретация заключается в том, что безопасность на уровне строк создает прямой путь с использованием связей таблиц. Итак, при добавлении USERELATIONSHIP() это иногда может привести к циклической ссылке, которая не существовала бы, если бы RLS не был включен.

3. Чтобы убедиться, что я понимаю: RLS всегда находится в состоянии on при использовании, поэтому он всегда активно использует обычно активные физические отношения. При попытке вычислить меру с помощью USERELATIONSHIP эти физические связи нельзя отключить, чтобы избежать циклической ссылки, поскольку они используются, а RLS имеет приоритет для безопасности. Что-то вроде блокировки «используемого файла». Это правильно?

Ответ №2:

Я хотел бы добавить к ответу @user9824134, который, к сожалению, не содержал большого объяснения (невозможно редактировать).

Почему TREATAS :

  • В документах объясняется, что эта функция применяет результат первого аргумента ( clientID ) к столбцу во втором аргументе ( 'ANSAPBICustomerTransDetailed'[SiteID] )

Почему это работает:

  • Не совсем уверен, как RLS применяет совместный путь, но идея «всегда включенного», объясненная @asp8811, имеет смысл для меня.
  • По TREATAS сути, это работает как альтернатива CROSSFILTER в этом случае. Применяя фильтр clientID к SiteID столбцу ANSAPBICustomerTransDetailed таблицы, он эмулирует CROSSFILTER .
  • Мне пришлось бы проверить эффективность, но я подозреваю, что производительность должна быть аналогичной, поскольку VALUES уже возвращает только отдельный список.

Приведенный ниже подход также работает и намного короче. CALCULATETABLE Выражение ничего не делает, если ему не передан фильтр, поэтому достаточно простого использования VALUES .

 TTipsInvs =
VAR clientID = VALUES ( ANSAPBISites[Site ID] )
VAR SalesValue =
    CALCULATE (
        SUM ( ANSAPBICustomerTransDetailed[Outstanding] ),
        TREATAS ( clientID, 'ANSAPBICustomerTransDetailed'[SiteID] ) )
RETURN
    IF ( ISBLANK ( SalesValue ), 0, ( SalesValue ) )
 

Ответ №3:

Провел быстрый тест: и, похоже, это работает без необходимости включения или отключения связей.

Модель

Перед RLS: Перед RLS

После RLS: После RLS

Комментарии:

1. Привет @mxix, от сайта до сайта клиента — это соотношение 1: 1, а не 1: M — у клиента может быть много сайтов, но на сайте есть только одна запись клиента. Из-за этого я не могу фактически активировать связь, которую вы описали выше. Есть идеи?