Build Power BI Columns That Adapt to Each User
Build Power BI Columns That Adapt to Each User
构建能够适应不同用户的 Power BI 列
Originally published at https://shai-kr.github.io/data-ninja-ai-lab/blog/2026-05-28-user-aware-calculated-columns-power-bi.html. Power BI calculated columns are getting a new design option that is easy to underestimate. The setting is called Expression Context. The option is User Context. The result is a calculated column that can be evaluated at query time, under the security context of the user who is running the report. 本文最初发布于 https://shai-kr.github.io/data-ninja-ai-lab/blog/2026-05-28-user-aware-calculated-columns-power-bi.html。Power BI 计算列迎来了一个容易被低估的新设计选项。该设置被称为“表达式上下文”(Expression Context),其中的选项为“用户上下文”(User Context)。其结果是,计算列可以在查询时,根据运行报表的用户所处的安全上下文进行评估。
That opens a useful set of patterns for semantic model authors: values that change by user culture; row-level calculations that do not need to be stored as physical columns; sensitive values that can stay visible to admins and blank for restricted users; Direct Lake and Import models that need cleaner control over calculated column materialization. The feature is still preview territory, so I would not treat it as a casual modeling shortcut. But it is already worth understanding because it changes how we think about calculated columns in Power BI. 这为语义模型作者开启了一系列实用的模式:根据用户文化而变化的值;无需存储为物理列的行级计算;对管理员可见但对受限用户显示为空的敏感值;以及需要更精细控制计算列物化(materialization)的 Direct Lake 和导入模型。该功能目前仍处于预览阶段,因此我不建议将其视为随意的建模捷径。但它非常值得了解,因为它改变了我们对 Power BI 中计算列的思考方式。
Source: SQLBI: Introducing user-aware calculated columns in Power BI 来源:SQLBI: Introducing user-aware calculated columns in Power BI
What changes with User Context
“用户上下文”带来了什么变化
A standard calculated column is evaluated when the table is processed. In Import mode, the result is stored in the semantic model. Once it is processed, the value is the same for every user who queries the model. A user-aware calculated column changes that behavior. When Expression Context is set to User Context, the expression is evaluated at query time. It runs under the active user security context, and it can use user-aware DAX functions such as: USERCULTURE(), USERPRINCIPALNAME(), USEROBJECTID(), USERNAME(), CUSTOMDATA(). 标准的计算列在表处理时进行评估。在导入模式下,结果会存储在语义模型中。一旦处理完成,对于查询该模型的每个用户,其值都是相同的。而“用户感知”计算列改变了这种行为。当表达式上下文设置为“用户上下文”时,表达式会在查询时进行评估。它在当前用户的安全上下文中运行,并可以使用用户感知 DAX 函数,例如:USERCULTURE()、USERPRINCIPALNAME()、USEROBJECTID()、USERNAME()、CUSTOMDATA()。
That means the column can still behave like a column in the model, but the value can depend on who is asking the question. I would think about it as a semantic model design tool, not only as a localization feature. 这意味着该列在模型中依然表现得像一个普通列,但其值取决于查询者是谁。我认为这不仅是一个本地化功能,更是一个语义模型设计工具。
Pattern 1: build reports that speak the user language
模式 1:构建能够使用用户语言的报表
The cleanest first use case is localization. A Date table can expose month names or day names that change based on the user’s culture. For example: 最直观的首个用例是本地化。日期表可以根据用户的文化显示不同的月份或日期名称。例如:
Month = FORMAT ( DATE ( 2020, 'Date'[Month Number], 1 ), "mmmm", USERCULTURE() )
If the user culture is English, the report can show January. If the user culture is French, the same column can show janvier. The model does not need separate month-name columns for every language. The expression can return the correct value at query time. This is where the feature becomes practical. Many organizations serve the same report to users in different regions. The metadata translation story already exists for names of tables, columns, and measures. User-aware calculated columns add another piece: values inside the model can adapt too. 如果用户文化是英语,报表可以显示 January;如果用户文化是法语,同一列可以显示 janvier。模型不需要为每种语言创建单独的月份名称列,表达式可以在查询时返回正确的值。这就是该功能实用之处。许多组织为不同地区的用户提供相同的报表。元数据翻译功能已经支持表、列和度量值的名称,而用户感知计算列补充了缺失的一环:模型内部的值也可以进行适配。
The slicer detail that matters
切片器中需要注意的细节
Localization creates a subtle modeling problem. If a slicer stores the selected value as translated text, that selection may not survive when the same report is viewed in another culture. For example, a slicer selection of Sunday does not match dimanche. The better design is to let the user see the translated label but keep the selection anchored to a stable key, such as Day of Week Number. That is where Sort by Column and Group By Columns matter. 本地化带来了一个微妙的建模问题。如果切片器将选定的值存储为翻译后的文本,那么当在另一种文化环境下查看同一报表时,该选择可能失效。例如,切片器中选定的 Sunday 与 dimanche 不匹配。更好的设计是让用户看到翻译后的标签,但将选择锚定在一个稳定的键上,例如“星期几编号”。这就是“按列排序”和“分组列”发挥作用的地方。
The principle is simple: display the user-aware text column; sort it by a numeric column; group it by the stable numeric identifier; avoid storing report selections as translated strings. That is the difference between a nice demo and a report that behaves correctly across languages. 原则很简单:显示用户感知的文本列;按数字列对其进行排序;按稳定的数字标识符进行分组;避免将报表选择存储为翻译后的字符串。这就是精美的演示与跨语言正确运行的报表之间的区别。
Pattern 2: create virtual columns for row-level calculations
模式 2:为行级计算创建虚拟列
The second pattern is less obvious and probably more important for model design. A user-aware calculated column is not materialized in Import mode. It exists in the model, but its values are not stored as a physical column in memory. That can be useful for simple row-level expressions. 第二个模式不太明显,但对于模型设计可能更重要。用户感知计算列在导入模式下不会被物化。它存在于模型中,但其值不会作为物理列存储在内存中。这对于简单的行级表达式非常有用。
As a User Context column, the same expression can behave more like a virtual column. It remains available to visuals, filters, slicers, and measures, but it does not need to be stored in the model. This is useful when the expression is simple enough for the engine to compute efficiently during query execution. 作为“用户上下文”列,同样的表达式表现得更像一个虚拟列。它对视觉对象、筛选器、切片器和度量值依然可用,但无需存储在模型中。当表达式足够简单,引擎可以在查询执行期间高效计算时,这种方式非常有用。
The practical takeaway: User Context can reduce stored model bloat, but it moves work to query time. That tradeoff needs measurement. 实际结论是:用户上下文可以减少模型存储的臃肿,但它将计算压力转移到了查询时。这种权衡需要进行评估。
Pattern 3: keep one report layout while hiding sensitive values
模式 3:在保持报表布局的同时隐藏敏感值
The third pattern is security-aware modeling. Object-level security can hide a column completely. That is sometimes the right answer, but it can break report visuals that reference the hidden column. User-aware calculated columns give another option for some scenarios: keep the column available in the report, but return blank values for restricted users. 第三个模式是安全感知建模。对象级安全性(OLS)可以完全隐藏一列。这有时是正确的做法,但可能会破坏引用该隐藏列的报表视觉对象。用户感知计算列为某些场景提供了另一种选择:在报表中保留该列,但对受限用户返回空值。
The key design choice is that the sensitive lookup table stays disconnected from the main customer table. That matters because the RLS filter should block the lookup result. It should not propagate through relationships and remove the customer rows or sales rows from the report. 关键的设计选择是,敏感的查找表应与主客户表保持断开连接。这一点很重要,因为行级安全性(RLS)筛选器应该阻止查找结果,而不应通过关系传播并从报表中移除客户行或销售行。