microsoft / CDM

The Common Data Model (CDM) is a standard and extensible collection of schemas (entities, attributes, relationships) that represents business concepts and activities with well-defined semantics, to facilitate data interoperability. Examples of entities include: Account, Contact, Lead, Opportunity, Product, etc.
https://powerplatform.microsoft.com/en-us/common-data-model/
Creative Commons Attribution 4.0 International
1.67k stars 526 forks source link

Need examples in c# for adding is.constrainedList traits #241

Closed Akkilz closed 3 years ago

Akkilz commented 3 years ago

I am trying to add constrainedToList, through sdk able to set true but need guidlines to add for the specific entity / attribute. I gone through doc's, its says via constantEntity ref to attribute can be achieved but need complete example.

https://docs.microsoft.com/en-us/common-data-model/sdk/logical-definitions

ConstantEntity - An association between an entity schema and a constant array of data values that exist only within the metadata documents. Used to represent tables of values.

constant-entity-object

I tried to add appliedTraits in abstract site.cdm.json, in the entity visualizer it was showing properly image

when i resolve its not showing the resolved site.cdm.json, not sure what i am missing. Plz find site.zip it has abstract & resolved version of site entity.

site.zip

Akkilz commented 3 years ago

After checking the scema doc's I was able to add in logical entity attribute & not sure this way is right & I need sample in c# for adding this.

image

{ "name": "Type", "dataType": { "dataTypeReference": "listLookup", "appliedTraits": [ { "traitReference": "does.haveDefault", "arguments": [ { "entityReference": { "explanation": "The constantValues below correspond to the attributes of the 'listLookupValues' entityShape which are: {languageTag, displayText, attributeValue, displayOrder}", "entityShape": "listLookupValues", "constantValues": [ [ "en", "Education", "Education", "0" ], [ "en", "Health Care", "Health Care", "1" ] ] } } ] } ] }, "description": "Type of site", "maximumLength": 75, "valueConstrainedToList": true }

image

llawwaii commented 3 years ago

Hi @Akkilz, We actually have a sample to show how to add a trait reference to means.relationship.verbPhrase which is similar to is.constrainedList, please check both traits' definitions below:

{
    "traitName": "is.constrainedList",
    "extendsTrait": "is",
    "explanation": "the values of an attribute are taken from or looked up from a fixed list of possibilities",
    "hasParameters": [
      {
        "name": "defaultList",
        "dataType": {
          "dataTypeReference": "entity",
          "appliedTraits": [
            {
              "traitReference": "means.entityName.specific",
              "arguments": [
                "listLookupValues"
              ]
            }
          ]
        }
      }
    ],
    "associatedProperties": [
      "valueConstrainedToList"
    ]
 },
 {
    "traitName": "means.relationship.verbPhrase",
    "extendsTrait": "means.relationship",
    "explanation": "The Verb Phrase used to model the relationship between the FROM entity and the TO entity.",
    "hasParameters": [
      {
        "name": "verbPhrase",         
        "explanation": "the localized Verb Phrase",
        "dataType": {
          "dataTypeReference": "entity",
          "appliedTraits": [
            {
              "traitReference": "means.entityName.specific",
              "arguments": [
                "localizedTable"
              ]
            }
          ]
        }
      }
    ]
  }

The following code is copied from the sample 6-create-net-new-entities


// The purpose "meaningOfRelationshipVerbPhrases" is from /samples/example-public-standards/foundations.cdm.json
// With the use of this purpose, two additional traits ("means.relationship.verbPhrase" and "means.relationship.inverseVerbPhrase") will be added by default
// as they are attached to the purpose definition.
CdmPurposeReference purposeRef = cdmCorpus.MakeRef<CdmPurposeReference>(CdmObjectType.PurposeRef, "meaningOfRelationshipVerbPhrases", false);

// You can add your own argument to the additional traits 
// The trait "means.relationship.verbPhrase" is also from /samples/example-public-standards/foundations.cdm.json
// This trait states that the data type it requires is an entity "localizedTable", which allow you to define phrases in different languages
CdmTraitReference forwardPurposeTraitReference = cdmCorpus.MakeObject<CdmTraitReference>(CdmObjectType.TraitRef, "means.relationship.verbPhrase", false);

List<List<string>> forwardDescriptions = new List<List<string>> { 
    new List<string>() { "en", $"{customMessage} - Forwards" }, 
    new List<string>() { "cn", "正向" } 
};

var forwardConstEntDef = cdmCorpus.MakeObject<CdmConstantEntityDefinition>(CdmObjectType.ConstantEntityDef, null, false);
forwardConstEntDef.ConstantValues = forwardDescriptions;

// The entity "localizedTable" is from /samples/example-public-standards/foundations.cdm.json
forwardConstEntDef.EntityShape = cdmCorpus.MakeRef<CdmEntityReference>(CdmObjectType.EntityRef, "localizedTable", true);
forwardPurposeTraitReference.Arguments.Add(null, cdmCorpus.MakeRef<CdmEntityReference>(CdmObjectType.EntityRef, forwardConstEntDef, true));

purposeRef.AppliedTraits.Add(forwardPurposeTraitReference);

After running the sample, you would get the following in the CustomAccount.cdm.json:

"purpose": {
  "purposeReference": "meaningOfRelationshipVerbPhrases",
  "appliedTraits": [
    {
      "traitReference": "means.relationship.verbPhrase",
      "arguments": [
        {
          "entityReference": {
            "entityShape": "localizedTable",
            "constantValues": [
              [
                "en",
                "Non-simple resolution guidance sample - Forwards"
              ],
              [
                "cn",
                "正向"
              ]
            ]
          }
        }
      ]
    }
  ]
}
Akkilz commented 3 years ago
entityAttribute.ValueConstrainedToList = true;

                CdmDataTypeReference dataTypeRef = cdmCorpus.MakeRef<CdmDataTypeReference>(CdmObjectType.DataTypeRef, "listLookup", true);
                CdmTraitReference forwardDataTypeTraitReference = cdmCorpus.MakeObject<CdmTraitReference>(CdmObjectType.TraitRef, "does.haveDefault", false);
                List<List<string>> forwardDescriptions = new List<List<string>>();
                var index = 0;
                property.Enum.ForEach(item =>
                {
                    forwardDescriptions.Add(new List<string>()
                    {
                        "en", item, item, index.ToString()
                    });

                    index++;
                });

                var forwardConstEntDef = cdmCorpus.MakeObject<CdmConstantEntityDefinition>(CdmObjectType.ConstantEntityDef, null, false);
                forwardConstEntDef.Explanation = "The constantValues below correspond to the attributes of the 'listLookupValues' entityShape which are: {languageTag, displayText, attributeValue, displayOrder}";
                forwardConstEntDef.ConstantValues = forwardDescriptions;
                forwardConstEntDef.EntityShape = cdmCorpus.MakeRef<CdmEntityReference>(CdmObjectType.EntityRef, "listLookupValues", true);
                forwardDataTypeTraitReference.Arguments.Add(null, cdmCorpus.MakeRef<CdmEntityReference>(CdmObjectType.EntityRef, forwardConstEntDef, true));
                dataTypeRef.AppliedTraits.Add(forwardDataTypeTraitReference);

                entityAttribute.DataType = dataTypeRef;

I am trying to achieve this, image

Instead i got image

I am not sure what i am missing & purpose is working fine, as per cdm doc's i needed listLookup default values. Is there any guidelines is available ?

Akkilz commented 3 years ago

my bad its working, CdmDataTypeReference dataTypeRef = cdmCorpus.MakeRef(CdmObjectType.DataTypeRef, "listLookup", false);

Akkilz commented 3 years ago

i am able to do dataType field list lookup in c#