salesforce零基础学习(一百二十七)Custom Metadata Type 篇二

本篇参考:

 salesforce零基础学习(一百一十一)custom metadata type数据获取方式更新

https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_methods_system_custom_metadata_types.htm

https://help.salesforce.com/s/articleView?id=sf.custommetadatatypes_overview.htm&language=en_US&type=5

https://trailhead.salesforce.com/content/learn/modules/custom_metadata_types_dec/cmt_overview

https://developer.salesforce.com/docs/atlas.en-us.224.0.apexcode.meta/apexcode/apex_class_Metadata_Operations.htm

我们在之前的篇中简单描述了 custom metadata type的使用,最开始的 custom metadata type是来建议取代 list custom setting,好处是可以基于metadata进行部署,不用像custom setting基于数据方式,容易出现漏部署情况,所以基于当时的版本来说, custom metadata type相对 list custom setting来说好处是基于metadata部署避免遗漏。

随着 custom metadata type的不断升级,目前增加了很多吸引人的点,主要是针对 Metadata Relationship字段类型的展开,接下来我们看一下这个新的类型可以实现的内容和场景。

一. Metadata Relationship类型

当我们在 custom metadata type创建字段时,目前字段类型增加了Metadata Relationship类型,此种类型可以设置两类的关联关系。

  • 关联到其他的custom metadata type,比如metadata type中维护省和市的信息,可以在市的metadata type中关联到省的metadata type。

  • 关联到salesforce标准的表或者自定义表/字段的实例中,比如关联到 Account表的 Industry字段(场景可以基于配置方式设置 default value)。

 当我们点击此类型创建的下一步,会让你选择系统已经存在的 custom metadata type还是选择 Entity Definition。需要注意的是,如果你的系统曾经已经创建过 Entity Definition,那样以后的步骤中,还会再列表中可以选择 Field Definition以及Entity Particle,这个在下面图中会有涉及。

demo中会创建这两种类型,其中关联自定义 metadata type的创建步骤不在此处罗列,主要讲一下 Entity Definition相关的关联,当我们创建了关联到 Entity Definition的字段以后,我们继续创建 Metadata Relationship类型的字段,就可以看到下图内容。其中:

  • Field Definition:关联的是上述选定的表的标准或者自定义字段
  • Entity Particle:关联的是上述选定的表的标准字段中的复合类型字段或者地理信息类型字段。

 当我们选择 Field Definition类型以后,点击下一步会选择 controling field,这样就会实现当选择某个表信息以后,就可以选择到当前这个表的字段。

 当我们创建表相关的表数据以后,我们就可以为custom metadata type设置数据,下图demo中维护了Account Customer Priority(自定义字段)默认值的一条数据,我们可以看到当Object Name选择了 Account以后,Field Name就可以自动的基于Account(作为 controling field)选择到 Account表中的字段。

这里针对父子的场景不做一步一步处理,感兴趣的可以基于下图进行数据的创建。

二. Custom Metadata Type使用场景介绍

1. 字段default value: 我们在项目上,有时需要在字段级别或者后台代码设置字段的默认值。原有方式是可以基于类型进行设置,比如picklist可以通过选择,其他类型就在 Default Value处设置初始值。apex端设置可以通过Custom Label或者hardcode方式写。除此以外,我们建议使用 Custom Metadata Type来统一维护初始值设置。UI方面可以基于指定的写法进行设置,格式如下图所示。

 

2. 用于validation rule / formula / process builder:这里只针对validation rule进行举例,写法相同。举个例子,当系统validation rule需要配置的规则用于很多表,并且这个值可能是动态修改的,我们不能每次变更都修改所引用到的所有的validation rule,这时我们可以基于custom metadata type进行配置来更好的可配置化管理。

 三. 通过apex class获取 custom metadata type

1. 获取 field Definition类型的metadata type数据

基于 apex端,我们可以通过基于metadata的方式,或者基于SOQL搜索方式获取到这条数据,然后获取这条数据的信息,下方的demo仅供参考。

 1). 通过 custom metadata type的getInstance方式获取。此方法前提是你需要了解到这个metadata type的 Name信息。

Default_Value__mdt defaultValue = Default_Value__mdt.getInstance('Account_Customer_Priority_Default');
system.debug('*** default value: ' + defaultValue.Default_Value__c);

2). 通过表字段的名称获取(这里代码可以进行优化,目前demo中的场景为有且仅有一条配置)。这里我们通过 FieldDefinition获取了当前表的 DurableId,原因是custom metadata type返回的 Field Definition是 DurableId,这个表会在下一篇博客做一些介绍。

List<Default_Value__mdt> defaultValueList = Default_Value__mdt.getAll().values();

Default_Value__mdt defaultValue;

List<FieldDefinition> fieldDefinitionList = [SELECT Id, DeveloperName, DurableId 
                                                FROM FieldDefinition  
                                                WHERE DeveloperName = 'Customer_Priority' 
                                                AND EntityDefinition.QualifiedApiName = 'Account'];
//TODO 实际项目中禁止此种写法,需要非空判断
String customerPriorityDurableId = fieldDefinitionList.get(0).DurableId;

for(Default_Value__mdt valueItem : defaultValueList) {
    if('Account'.equalsIgnorecase(valueItem.Object_Name__c) 
        && customerPriorityDurableId.equalsIgnorecase(valueItem.Field_Name__c)) {
        defaultValue = valueItem;
    }
}

if(defaultValue != null) {
    system.debug('*** default value : ' + defaultValue.Default_Value__c);
}

2. 获取到关联其他metadata type的数据

1). 通过 custom metadata type的getInstance方式获取,方式同上,不做说明。

 2) 通过关联父表的数据的developerName进行获取(这里代码可以进行优化,目前demo中的场景为有且仅有一条配置)。

List<Default_Value__mdt> defaultValueList = Default_Value__mdt.getAll().values();

Default_Value__mdt targetDefaultValue;

for(Default_Value__mdt valueItem : defaultValueList) {
    if(String.isNotBlank(valueItem.Parent_Metadata_Type__c) 
        && 'test_parent'.equalsIgnorecase(valueItem.Parent_Metadata_Type__r.DeveloperName)) {
        targetDefaultValue = valueItem;
    }
}

system.debug(JSON.serialize(targetDefaultValue));

我们看一下目标数据通过 getAll返回的JSON结构,我们会发现如果有负责结构内容,会将复结构的信息同样返回。

{
    "MasterLabel": "TEST_RELATION_WITH_PARENT", 
    "NamespacePrefix": null, 
    "QualifiedApiName": "TEST_RELATION_WITH_PARENT", 
    "Parent_Metadata_Type__c": "m005g000002FMry", 
    "Language": "zh_CN", 
    "attributes": {
        "type": "Default_Value__mdt", 
        "url": "/services/data/v57.0/sobjects/Default_Value__mdt/m025g000000rtgz"
    }, 
    "DeveloperName": "TEST_RELATION_WITH_PARENT", 
    "Id": "m025g000000rtgz", 
    "Parent_Metadata_Type__r": {
        "attributes": {
            "type": "Parent_Metadata_Type__mdt"
        }, 
        "DeveloperName": "test_parent"
    }, 
    "Field_Name__c": null, 
    "Object_Name__c": null, 
    "Label": "TEST_RELATION_WITH_PARENT", 
    "SystemModstamp": "2023-03-15T10:00:03.000+0000", 
    "Default_Value__c": null
}

总结:本篇主要是介绍了一下 metadata type除取代list custom setting以外的其他的使用场景以及使用apex获取的方式。篇中的demo也仅用于获取数据用,对判断,逻辑,可行性操作都可以进一步优化。篇中有错误地方欢迎指出,有不懂欢迎留言。

posted @ 2023-03-15 18:31  zero.zhang  阅读(293)  评论(0编辑  收藏  举报