Projection - Operation Replace as Foreign Key
Overview
ReplaceAsForeignKey is a projection operation that creates a foreign key that references one of the source attributes. This operation receives a set of attributes as input and outputs a single foreign key attribute, which is specified on the replaceWith
property. A is.linkedEntity.identifier
trait is added to the resulting attribute. The argument of this trait has information about the source attribute that is referenced by this foreign key.
{
"traitReference": "is.linkedEntity.identifier",
"arguments": [
{
"entityReference": {
"entityShape": "entityGroupSet",
"constantValues": [
[
"<Path to entity>",
"<Attribute name>",
"<Relationship name>"
]
]
}
}
]
}
Note: you can access the API reference for this operation on this link.
Note: The foreign key attributes are used by the Object Model to calculate relationships.
Examples
The examples below refer to the Person
entity as defined here.
{
"entityName": "Person",
"hasAttributes": [
{
"name": "name",
"dataType": "string"
},
{
"name": "age",
"dataType": "integer"
},
{
"name": "address",
"dataType": "string"
},
{
"name": "phoneNumber",
"dataType": "string"
},
{
"name": "email",
"dataType": "string"
}
]
}
Using the ReplaceAsForeignKey operation on an entity attribute
If we have an entity attribute, we can use ReplaceAsForeignKey to create a foreign key attribute.
{
"name": "PersonInfo",
"entity": {
"source": "Person",
"operations": [
{
"$type": "replaceAsForeignKey",
"reference": "name",
"replaceWith": {
"name": "personFK",
"dataType": "entityId"
}
}
]
}
}
The resulting resolved PersonInfo entity typed attribute is:
PersonInfo |
---|
personFK |
The is.linkedEntity.identifier
trait on the personFK
attribute looks like the following:
{
"traitReference": "is.linkedEntity.identifier",
"arguments": [
{
"entityReference": {
"entityShape": "entityGroupSet",
"constantValues": [
[
"Person.cdm.json/Person",
"name",
"PersonInfo_Person"
]
]
}
}
]
}
Using the ReplaceAsForeignKey operation when extending an entity
If we have an entity that extends another entity, we can use ReplaceAsForeignKey to create a foreign key attribute.
Given an entity, Child, that extends from the Person entity:
{
"entityName": "Child",
"extendsEntity": {
"source": "Person",
"operations": [
{
"$type": "replaceAsForeignKey",
"reference": "name",
"replaceWith": {
"name": "personFK",
"dataType": "entityId"
}
}
]
},
"hasAttributes": []
}
The resulting resolved Child entity is:
Child |
---|
personFK |
Using the ReplaceAsForeignKey operation to create a multi part foreign key
On the examples above, the foreign keys created are identified by one attribute only. In some cases one attribute alone is not capable of uniquely identifying a relationship, for example there might be multiple people with the same name. For these cases, we can create a relationship that is composed by multiple attributes as below.
{
"name": "PersonInfo",
"entity": {
"source": "Person",
"operations": [
{
"$type": "replaceAsForeignKey",
"reference": "name",
"replaceWith": {
"name": "nameFK",
"dataType": "entityId"
}
},
{
"$type": "replaceAsForeignKey",
"reference": "address",
"replaceWith": {
"name": "addressFK",
"dataType": "entityId"
}
}
]
}
}
The resulting resolved PersonInfo entity typed attribute is:
PersonInfo |
---|
nameFK |
addressFK |
Let us have a look at the is.linkedEntity.identifier
trait on both these resulting attributes.
First nameFK
:
{
"traitReference": "is.linkedEntity.identifier",
"arguments": [
{
"entityReference": {
"entityShape": "entityGroupSet",
"constantValues": [
[
"Person.cdm.json/Person",
"name",
"PersonInfo_Person"
]
]
}
}
]
}
Now addressFK
:
{
"traitReference": "is.linkedEntity.identifier",
"arguments": [
{
"entityReference": {
"entityShape": "entityGroupSet",
"constantValues": [
[
"Person.cdm.json/Person",
"address",
"PersonInfo_Person"
]
]
}
}
]
}
By looking at the two traits above, you can see that both the relationship names are the same PersonInfo_Person
. This is an indicator that these attributes combined make up the relationship foreign key.
Using the ReplaceAsForeignKey operation to create a polymorphic relationship
For this example, we will use another entity called ContactKinds
that has three entity attributes pointing to Email
, Phone
and Social
.
{
"entityName": "ContactKinds",
"hasAttributes": [
{
"name": "emailKind",
"entity": "Email"
},
{
"name": "phoneKind",
"entity": "Phone"
},
{
"name": "socialKind",
"entity": "Social"
}
]
}
Phone | Social | |
---|---|---|
emailId | phoneId | socialId |
address | number | account |
isPrimary | isPrimary | isPrimary |
This entity defines three different methods that a customer can be contact at. We want to create an entity attribute that is a foreign key to one of email, phone or social. To achieve this goal, we will use the ReplaceAsForeignKey along with CombineAttributes. Note that because ContactKinds
is a polymorphic entity we need to set the isPolymorphicSource
property to true.
{
"name": "ContactAt",
"isPolymorphicSource": true,
"entity": {
"source": "ContactKinds",
"runSequentially": true,
"operations": [
{
"$type": "combineAttributes",
"select": [ "emailId", "phoneId", "socialId" ],
"mergeInto": {
"name": "contactAtId",
"dataType": "entityId"
}
},
{
"$type": "replaceAsForeignKey",
"reference": "contactAtId",
"replaceWith": {
"name": "contactAtFK",
"dataType": "entityId"
}
},
{
"$type": "addTypeAttribute",
"typeAttribute": {
"name": "contactAtType",
"dataType": "integer"
}
}
]
}
}
The resulting resolved ContactAt entity typed attribute is:
ContactAt |
---|
contactAtFK |
contactAtType |
NOTE: in this case the attribute, contactAtFK
holds a foreign key to email, phone or social. We also used a AddTypeAttribute operation to create an attribute that is used to specify which entity contactAtFK
is pointing to per-record. Adding the type attribute is not required, but useful.
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour