Table of Contents

如何使用注释和扩展属性

注释是纯信息性的元数据,不会影响模型的行为。 它们对自动化和脚本编写非常有用。 扩展属性旨在用于需要特定支持的客户端工具扩展。 例如,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 类型,其值可以是 StringJson

// 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

另见