Table of Contents

Cómo trabajar con anotaciones y propiedades extendidas

Las anotaciones son metadatos meramente informativos y no afectan al comportamiento del modelo. Son útiles para la automatización y la creación de scripts. Las propiedades extendidas están pensadas para extensiones de herramientas cliente que requieren compatibilidad específica. Por ejemplo, los parámetros de campo de Power BI dependen de las propiedades extendidas, por lo que esta característica solo está disponible en Power BI.

Referencia rápida

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

Configurar y leer anotaciones

Cualquier objeto que implemente (xref:TabularEditor.TOMWrapper.IAnnotationObject) admite anotaciones. Esto incluye tablas, columnas, medidas, jerarquías, particiones, perspectivas, roles, Data sources y relaciones.

Etiqueta las medidas generadas automáticamente para que un script posterior pueda identificarlas y actualizarlas:

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

Más adelante, recupera todas las medidas etiquetadas por ese script:

var autoGenerated = Model.AllMeasures.Where(m => m.GetAnnotation("GeneratedBy") == "DateTableScript");

Comprobar y eliminar anotaciones

Usa HasAnnotation() para condicionar la lógica a la presencia de una etiqueta:

// Skip measures that are flagged for manual review
if (m.HasAnnotation("NeedsReview")) return;

Usa RemoveAnnotation() para limpiar claves obsoletas en todo el modelo:

// Remove a deprecated annotation key from all measures that still carry it
Model.AllMeasures
    .Where(m => m.HasAnnotation("LegacyTag"))
    .ForEach(m => m.RemoveAnnotation("LegacyTag"));

Recorrer todas las anotaciones de un objeto

GetAnnotations() devuelve los nombres de las anotaciones. Usa GetAnnotation(name) para recuperar los valores.

foreach (var name in m.GetAnnotations())
{
    var value = m.GetAnnotation(name);
    Info($"{name} = {value}");
}

Uso del indexador de la colección Annotations

La propiedad Annotations proporciona acceso mediante indexador como alternativa a la API basada en métodos.

m.Annotations["key"] = "value";        // set
var val = m.Annotations["key"];            // get

Operaciones masivas con anotaciones

Etiqueta objetos o quita etiquetas en todo el modelo.

// 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");
    });

Propiedades extendidas

Las propiedades extendidas funcionan de forma similar a las anotaciones, pero admiten un ExtendedPropertyType tipado, ya sea String o 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"];

Equivalente en LINQ dinámico

En las expresiones de reglas de BPA, los métodos de anotación se invocan directamente sobre el objeto del contexto.

C# Script LINQ dinámico (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

Ver también