{"id":620,"date":"2023-12-30T19:00:30","date_gmt":"2023-12-30T18:00:30","guid":{"rendered":"https:\/\/www.csopro.de\/biblog\/?p=620"},"modified":"2023-12-30T19:03:20","modified_gmt":"2023-12-30T18:03:20","slug":"achtung-bei-userelationship-und-row-level-security-in-tabularen-modellen","status":"publish","type":"post","link":"https:\/\/www.csopro.de\/biblog\/2023\/12\/achtung-bei-userelationship-und-row-level-security-in-tabularen-modellen\/","title":{"rendered":"Achtung bei USERELATIONSHIP() und Row Level Security in Tabularen Modellen"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Motivation<\/h2>\n\n\n\n<p>WIr hatten bei einem Kunden folgendes Szenario:<\/p>\n\n\n\n<p>Wir hatten einen Cube (tabular model), das wir ausreichend getestet hatten. Wir hatten auch Filter (Slices in Power BI bzw. Filter in Excel Pivot) auf das Attribut Land getestet.<\/p>\n\n\n\n<p>Als wir aber nun eine Rolle anlegten, die auf ein Land filterte, funktionierten unsere Berichte nicht mehr f\u00fcr diese Personen.<\/p>\n\n\n\n<p>Da mich das sehr \u00fcberrascht hat, m\u00f6chte ich hier die Details beschreiben.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Beispiel-Cube<\/h2>\n\n\n\n<p>Wir erstellen einen Cube mit 3 Tabellen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Country<\/li>\n\n\n\n<li>Lead<\/li>\n\n\n\n<li>Opportunity<\/li>\n<\/ul>\n\n\n\n<p>Leads und Opportunities haben jeweils ein Land &#8211; und sind damit mit der Tabelle Country verbunden.<\/p>\n\n\n\n<p>Opportunities k\u00f6nnen aus Leads hervorgehen. Daf\u00fcr haben Opportunities eine LeadID, die aber leer sein kann. Au\u00dferdem kann das Land des Leads unterschiedlich vom Land der daraus generierten Opportunity sein.<\/p>\n\n\n\n<p>Da diese Relationen einen Zirkel bedeuten w\u00fcrden, ist die Beziehung zwischen Lead und Opportunity auf inaktiv gesetzt &#8211; und kann dann \u00fcber <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">USERELATIONSHIP()<\/code> in einem Measure verwendet werden.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2023\/12\/grafik-17.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"579\" height=\"405\" src=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2023\/12\/grafik-17.png\" alt=\"\" class=\"wp-image-621\" srcset=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2023\/12\/grafik-17.png 579w, https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2023\/12\/grafik-17-300x210.png 300w\" sizes=\"auto, (max-width: 579px) 100vw, 579px\" \/><\/a><figcaption class=\"wp-element-caption\">Datenmodell mit aktiven und inaktiven Verbindungen<\/figcaption><\/figure>\n\n\n\n<p>Als Measures definieren wir:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Anzahl Leads:=COUNTROWS(Leads)\nAnzahl Opp:=COUNTROWS(Opportunities)\nAnzahl Opportunities via Leads:=CALCULATE(COUNTROWS(Opportunities), USERELATIONSHIP(Leads[LeadID],Opportunities[LeadID]))<\/pre>\n\n\n\n<p>In den Tabellen haben wir folgende Beispieldaten:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2023\/12\/grafik-20.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"578\" height=\"135\" src=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2023\/12\/grafik-20.png\" alt=\"\" class=\"wp-image-627\" srcset=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2023\/12\/grafik-20.png 578w, https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2023\/12\/grafik-20-300x70.png 300w\" sizes=\"auto, (max-width: 578px) 100vw, 578px\" \/><\/a><figcaption class=\"wp-element-caption\">Beispieldaten<\/figcaption><\/figure>\n\n\n\n<p>Somit ergeben sich f\u00fcr die Measures folgende Ergebnisse:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td>Filter<\/td><td>Measure<\/td><td>Wert<\/td><td>IDs<\/td><\/tr><tr><td>ohne<\/td><td>Anzahl Leads<\/td><td>3<\/td><td>1,2,3<\/td><\/tr><tr><td>ohne<\/td><td>Anzahl Opp<\/td><td>5<\/td><td>1,2,3,4,5<\/td><\/tr><tr><td>ohne<\/td><td>Anz Opp via Lead<\/td><td>5<\/td><td>1,2,3,4,5<\/td><\/tr><tr><td>Deutschland<\/td><td>Anzahl Leads<\/td><td>2<\/td><td>1,2<\/td><\/tr><tr><td>Deutschland<\/td><td>Anzahl Opp<\/td><td>3<\/td><td>1,4,5<\/td><\/tr><tr><td>Deutschland<\/td><td>Anz Opp via Lead<\/td><td>2<\/td><td>1,2<\/td><\/tr><tr><td>\u00d6sterreich<\/td><td>Anzahl Leads<\/td><td>1<\/td><td>3<\/td><\/tr><tr><td>\u00d6sterreich<\/td><td>Anzahl Opp<\/td><td>2<\/td><td>2,3<\/td><\/tr><tr><td>\u00d6sterreich<\/td><td>Anz Opp via Lead<\/td><td>1<\/td><td>3<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">Ergebnisse<\/figcaption><\/figure>\n\n\n\n<p>Soweit ist das wenig \u00fcberraschend. <\/p>\n\n\n\n<p>Wenn wir jetzt aber eine Rolle mit Row Level Security &#8211; Filter <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">=Country[Country]=\"Deutschland\"<\/code> definieren, so h\u00e4tte ich erwartet, dass wir die Werte erhalten, die in obiger Tabelle unter Deutschland stehen.<\/p>\n\n\n\n<p>Das stimmt auch f\u00fcr die beiden ersten Measures. Allerdings gibt das Measure &#8222;Anzahl Opportunities via Leads&#8220; folgenden Fehler zur\u00fcck:<\/p>\n\n\n\n<p><strong>Error: The UseRelationship() and CrossFilter() functions may not be used when querying &#8218;Opportunities&#8216; because it is constrained by row-level security defined on &#8218;Leads&#8216; or related tables.<\/strong><\/p>\n\n\n\n<p>Das finde ich sehr verbl\u00fcffend. Eigentlich halte ich das f\u00fcr einen Bug. Da er aber so (mindestens) seit SSAS 2016 enthalten ist, gehe ich davon aus, dass Microsoft das nicht so sieht.<\/p>\n\n\n\n<p>Deswegen sollte man mit <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">USERELATIONSHIP()<\/code> sehr sparsam umgehen, da sich dadurch Nebeneffekte auf Row Level Security ergeben.<\/p>\n\n\n\n<p>(Nur als Randbemerkung: Bei meinem Kunden hatte ich eine andere Fehlermeldung (ambiguous paths). Ich wei\u00df nicht, ob es am Patch-Level lag oder ich die Situation nicht 100% genau nachstellen konnte)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Motivation WIr hatten bei einem Kunden folgendes Szenario: Wir hatten einen Cube (tabular model), das wir ausreichend getestet hatten. Wir hatten auch Filter (Slices in Power BI bzw. Filter in Excel Pivot) auf das Attribut Land getestet. Als wir aber nun eine Rolle anlegten, die auf ein Land filterte, funktionierten unsere Berichte nicht mehr f\u00fcr &hellip; <a href=\"https:\/\/www.csopro.de\/biblog\/2023\/12\/achtung-bei-userelationship-und-row-level-security-in-tabularen-modellen\/\" class=\"more-link\"><span class=\"screen-reader-text\">Achtung bei USERELATIONSHIP() und Row Level Security in Tabularen Modellen<\/span> weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[63,9,84,1],"tags":[28,93,91,92],"class_list":["post-620","post","type-post","status-publish","format-standard","hentry","category-azure-anaysis-services","category-analysisservices","category-power-bi","category-uncategorized","tag-dax","tag-error","tag-ssas","tag-userelationship"],"_links":{"self":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/620","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/comments?post=620"}],"version-history":[{"count":5,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/620\/revisions"}],"predecessor-version":[{"id":629,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/620\/revisions\/629"}],"wp:attachment":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/media?parent=620"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/categories?post=620"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/tags?post=620"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}