Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Microsoft Dataverse customer tables (account, contact, and customeraddress) store customer relationships, contact details, and address and shipping information. This article explains how these tables relate and how to manage embedded and empty customer address records.
Account table
The account table is one of the tables in Dataverse to which most other tables are attached or parented. In Dataverse, an account represents a company with which the business unit has a relationship. Information that is included in an account is all relevant contact information, company information, category, relationship type, and address information. Other information that applies includes the following items:
- An account can be a parent to most table types, including another account.
- An account can be a standalone table.
- An account can have only one account as its parent.
- Accounts can have multiple child accounts and child contacts.
Account management is one of the important concepts of business-to-business customer relationship management (Dynamics 365) because an organization wants to see all the activities they have with another company. All these activities come together at the account level. View the Account table reference.
Contact table
In Dataverse, a contact represents a person, usually an individual, with whom a business unit has a relationship, such as a customer, a supplier, or a colleague. The contact table is one of the tables that most other tables are linked to. A contact can be a stand-alone table. Included in this table are professional, personal, and family information, and multiple addresses. View the Contact table reference.
Both accounts and contacts are part of managing customers and are related to one another in the following ways:
- A contact can be a parent to every other table except accounts and contacts.
- A contact can have only one account as its parent.
- A contact can be marked as the primary contact person for an account by setting the
Account.PrimaryContactIdcolumn.
The contact table stores information about a person such as an email address, street address, and telephone numbers. It also includes other related information, such as the person's birthday or anniversary date. Depending on the type of customers a business unit has, it needs either only contacts, or contacts and accounts, to give a full view of its customers.
Linking tables such as activities and notes to the contact table lets user see all the communication the user had with a customer, any actions the user took on behalf of the customer, and all information the user needs about the customer.
CustomerAddress table
This table contains more address and shipping information for customer records (account and contact). By default, Dataverse creates at least two customeraddress records in this table when you create a new customer record, even when there's no data for these records. Learn how you can change this behavior.
You can access all customeraddress records related to account and contact records through the Account_CustomerAddress and Contact_CustomerAddress relationships. Both relationships use the parentid lookup. The parentidtypecode column indicates the type of customer record the address is related to.
Address data embedded with customer records
You can retrieve or modify the data for the two or three embedded customeraddress records with the customer record.
- Account records have columns
address1_addressidandaddress2_addressid. - Contact records have columns
address1_addressid,address2_addressid, andaddress3_addressid.
These columns store customeraddressid values. Other customer columns, each prefixed with address1*, address2*, or address3*, contain the corresponding address information from the customeraddress table.
The customeraddress addressnumber column indicates which address applies to the parent customer record columns. You can't set the addressnumber column to a value used by another customeraddress record related to the same parent customer. You can set an existing addressnumber value to 0 or null, and then change the value of another record if you want to swap the relative position of the records for the customer records. While the addressnumber value increments for each record created for a customer, other than controlling the respective embedded address position in the customer record (either 1, 2, or 3), the addressnumber column value isn't used for any other purpose.
Dataverse only updates these customeraddress records through the corresponding customer record columns instead of updating the customeraddress rows directly. However, anyone can edit these records as customeraddress records, or add more customeraddress records associated with the account or contact record that aren't embedded with the account and contact records.
Deletion of embedded customer address rows isn't allowed
By default, if you attempt to delete one of the embedded customeraddress records that the address1_addressid, address2_addressid, or address3_addressid references for a customer record, you get an error like the following error message:
Name:
CannotDeleteDueToAssociation
Code:0x80040227
Number:-2147220953
Message:Customer Address can not be deleted because it is associated with another object. Address Id = 4f33c2e4-d5a3-4b03-b050-21984c0e4c15, AddressNumber=2, ParentId=4b757ff7-9c85-ee11-8179-000d3a9933c9, ObjectTypeCode=1
Learn how you can change this behavior
Disable empty record creation
Each row in the customeraddress table counts against the Dataverse capacity you pay for, so you might want to minimize this cost.
You can tell Dataverse not to create empty customeraddress table rows for each customer record by changing the Disable empty address record creation setting in the Power Platform admin center. Before changing this behavior, consider whether you have existing customizations that depend on default behavior. Learn more about this setting.
While this setting is on, no new empty customeraddress table rows are created when new customer records are created. Records are only created if the incoming payload contains address data. Normally, the payload only includes columns that have data. If there's no data for the columns, the columns aren't included in the payload and the values are null when the record is saved. However, if the payload contains address columns with values set to null, the address is created with null values. If you continue to see empty records being created, check how they're created and whether that client application is sending column data with null values.
If the Disable empty address record creation setting is switched off, the default behavior resumes. Turning on this setting doesn't delete any existing customeraddress table rows. Switching this setting back on after it was switched off doesn't re-create records that weren't created.
Detect whether empty address record creation is disabled
These example functions show how to detect whether the Disable empty address record creation setting is enabled in the environment.
This Test-IsEmptyAddressRecordCreationDisabled PowerShell function uses the Microsoft Power Platform CLI pac env list-settings command to check a value in the Organization.OrgDbOrgSettings column.
function Test-IsEmptyAddressRecordCreationDisabled {
$orgdborgsettings = pac env list-settings `
--filter orgdborgsettings `
| Where-Object { $_ -match '^orgdborgsettings\s+' } `
| ForEach-Object { $_ -replace '^orgdborgsettings\s+', '' }
$xml = [xml]$orgdborgsettings
$element = $xml.SelectSingleNode("//CreateOnlyNonEmptyAddressRecordsForEligibleEntities")
# Return true only when the element exists and has the value of 'true'
return ($null -ne $element) -and ($element.InnerText -eq 'true')
}
Delete embedded address records
By default, you can't delete embedded customeraddress table rows that the address1_addressid, address2_addressid, or address3_addressid columns in customer tables reference. For more information, see Deletion of embedded customer address rows isn't allowed.
The Enable Deletion of Address Records setting in the Power Platform admin center changes this behavior. Learn more about this setting.
Detect whether deletion of address records is enabled
These example functions show how to detect whether the Enable Deletion of Address Records setting is enabled in the environment.
This Test-IsDeleteAddressRecordsEnabled PowerShell function uses the Microsoft Power Platform CLI pac env list-settings command to check a EnableDeleteAddressRecords value in the Organization.OrgDbOrgSettings column.
function Test-IsDeleteAddressRecordsEnabled {
$orgdborgsettings = pac env list-settings `
--filter orgdborgsettings `
| Where-Object { $_ -match '^orgdborgsettings\s+' } `
| ForEach-Object { $_ -replace '^orgdborgsettings\s+', '' }
$xml = [xml]$orgdborgsettings
$element = $xml.SelectSingleNode("//EnableDeleteAddressRecords")
# Return true only when the element exists and has the value of 'true'
return ($null -ne $element) -and ($element.InnerText -eq 'true')
}
Bulk delete of empty customer address records
After you disable empty address record creation and enable deletion of address records, use the following example functions to asynchronously delete empty customeraddress records by using the BulkDelete message.
Bulk delete code examples
These functions are based on the Address (CustomerAddress) Writable columns/attributes and don't include any custom columns that might be in your environment. You might want to alter these queries if you need to include your custom columns.
The Start-BulkDeleteEmptyCustomerAddressRecords PowerShell function creates a system job to delete empty customeraddress records by using the Microsoft Power Platform CLI pac data bulk-delete schedule command.
This function depends on the example Test-IsDeleteAddressRecordsEnabled and Test-IsEmptyAddressRecordCreationDisabled functions described in Detect whether deletion of address records is enabled and Detect whether empty address record creation is disabled, respectively. The function creates the job only when both settings allow all empty customer address records to be deleted and prevent new empty records from being created.
function Start-BulkDeleteEmptyCustomerAddressRecords {
if (!(Test-IsDeleteAddressRecordsEnabled)) {
Write-Host 'Enable deletion of address records before running this function.'
return
}
if (!(Test-IsEmptyAddressRecordCreationDisabled)) {
Write-Host 'Disable empty address record creation before running this function.'
return
}
$fetchXml = @(
'<fetch>'
"<entity name='customeraddress'>"
"<attribute name='customeraddressid' />"
"<filter type='and'>"
"<condition attribute='city' operator='null' />"
"<condition attribute='country' operator='null' />"
"<condition attribute='county' operator='null' />"
"<condition attribute='fax' operator='null' />"
"<condition attribute='freighttermscode' operator='null' />"
"<condition attribute='latitude' operator='null' />"
"<condition attribute='line1' operator='null' />"
"<condition attribute='line2' operator='null' />"
"<condition attribute='line3' operator='null' />"
"<condition attribute='longitude' operator='null' />"
"<condition attribute='postalcode' operator='null' />"
"<condition attribute='postofficebox' operator='null' />"
"<condition attribute='primarycontactname' operator='null' />"
"<condition attribute='shippingmethodcode' operator='null' />"
"<condition attribute='stateorprovince' operator='null' />"
"<condition attribute='telephone1' operator='null' />"
"<condition attribute='telephone2' operator='null' />"
"<condition attribute='telephone3' operator='null' />"
"<condition attribute='upszone' operator='null' />"
"<condition attribute='utcoffset' operator='null' />"
'</filter>'
'</entity>'
'</fetch>'
) -join ''
pac data bulk-delete schedule `
--entity customeraddress `
--fetchxml $fetchXml `
--job-name 'Delete Empty Customer Address Records'
}