如何使用注释和扩展属性
注释是纯信息性的元数据,不会影响模型的行为。 它们对自动化和脚本编写非常有用。 扩展属性旨在用于需要特定支持的客户端工具扩展。 例如,Power BI 中的字段参数依赖扩展属性,因此此功能仅限 Power BI。
快速参考
// Annotations
obj.SetAnnotation("key", "value"); // set or create
obj.GetAnnotation("key") // returns string or null
obj.HasAnnotation("key") // returns bool
obj.RemoveAnnotation("key") // delete
obj.GetAnnotations() // IEnumerable<string> of annotation names
obj.ClearAnnotations() // remove all
obj.Annotations // AnnotationCollection (indexer access)
// Extended properties
obj.SetExtendedProperty("key", "value", ExtendedPropertyType.String);
obj.SetExtendedProperty("key", jsonStr, ExtendedPropertyType.Json);
obj.GetExtendedProperty("key") // returns string
obj.HasExtendedProperty("key") // returns bool
obj.RemoveExtendedProperty("key") // delete
obj.GetExtendedPropertyType("key") // String or Json
obj.ExtendedProperties // ExtendedPropertyCollection (indexer access)
设置和读取注释
任何实现 (xref:TabularEditor.TOMWrapper.IAnnotationObject) 接口的对象都支持注释。 其中包括表、列、度量值、层次结构、分区、透视、角色、数据源以及关系。
为自动生成的度量值添加标记,以便后续脚本识别并更新它们:
var m = Model.AllMeasures.First(m => m.Name == "Revenue");
m.SetAnnotation("GeneratedBy", "DateTableScript");
m.SetAnnotation("Owner", "Finance Team");
// Read it back
var owner = m.GetAnnotation("Owner"); // "Finance Team"
var missing = m.GetAnnotation("NoKey"); // null
稍后,检索由该脚本添加标记的所有度量值:
var autoGenerated = Model.AllMeasures.Where(m => m.GetAnnotation("GeneratedBy") == "DateTableScript");
检查并移除注释
使用 HasAnnotation() 根据是否存在某个标记来控制逻辑:
// Skip measures that are flagged for manual review
if (m.HasAnnotation("NeedsReview")) return;
使用 RemoveAnnotation() 清理整个模型中过时的键:
// Remove a deprecated annotation key from all measures that still carry it
Model.AllMeasures
.Where(m => m.HasAnnotation("LegacyTag"))
.ForEach(m => m.RemoveAnnotation("LegacyTag"));
遍历对象上的所有注释
GetAnnotations() 返回所有注释的名称。 使用 GetAnnotation(name) 获取值。
foreach (var name in m.GetAnnotations())
{
var value = m.GetAnnotation(name);
Info($"{name} = {value}");
}
使用 Annotations 集合的索引器
Annotations 属性提供索引器访问,可作为基于方法的 API 的替代方案。
m.Annotations["key"] = "value"; // set
var val = m.Annotations["key"]; // get
批量注释操作
在整个模型中为对象添加或移除标记。
// Tag all hidden measures
Model.AllMeasures
.Where(m => m.IsHidden)
.ForEach(m => m.SetAnnotation("ReviewStatus", "Hidden"));
// Migrate an annotation key from OldKey to NewKey
Model.AllMeasures
.Where(m => m.HasAnnotation("OldKey"))
.ForEach(m => {
m.SetAnnotation("NewKey", m.GetAnnotation("OldKey"));
m.RemoveAnnotation("OldKey");
});
扩展属性
扩展属性的用法与注释类似,但支持 ExtendedPropertyType 类型,其值可以是 String 或 Json。
// Store a JSON extended property (e.g., field parameter metadata)
var table = Model.Tables["Parameter"];
var json = "{\"version\":3,\"values\":[[\"Revenue\"],[\"Cost\"]]}";
table.SetExtendedProperty("ParameterMetadata", json, ExtendedPropertyType.Json);
// Read back
var value = table.GetExtendedProperty("ParameterMetadata");
var type = table.GetExtendedPropertyType("ParameterMetadata"); // ExtendedPropertyType.Json
// Indexer access
table.ExtendedProperties["key"] = "value";
var val = table.ExtendedProperties["key"];
Dynamic LINQ 等效写法
在 BPA 规则表达式中,可以直接对上下文中的对象调用注释方法。
| C# Script | Dynamic LINQ (BPA) |
|---|---|
m.GetAnnotation("key") == "value" |
GetAnnotation("key") = "value" |
m.HasAnnotation("key") |
HasAnnotation("key") |
m.GetAnnotation("key") != null |
GetAnnotation("key") != null |
m.GetAnnotationsCount() > 0 |
GetAnnotationsCount() > 0 |
另见
- @实用脚本片段
- 创建字段参数
- 如何导航 TOM 对象层次结构