アカウントと連絡先テーブルは、顧客の識別と管理、製品とサービスの販売、顧客に優れたサービスを提供するために不可欠です。 customeraddress テーブルには、顧客の住所と出荷情報が格納されます。
アカウント表
アカウント テーブルは、Dataverse 内のテーブルの 1 つであり、他のほとんどのテーブルがその下に配置されるか、親テーブルとして機能しています。 Dataverse では、アカウントは、部署がリレーションシップを持つ会社を表します。 取引先企業に含まれている情報は、関連するすべての取引先担当者情報、会社情報、カテゴリ、関係の種類、および住所情報です。 適用されるその他の情報には、次の項目が含まれています。
- アカウントは、他のアカウントを含め、ほとんどのテーブルの種類の親にすることができます。
- アカウントはスタンドアロン テーブルにすることができます。
- 1 つの取引先企業の上位にできる取引先企業は 1 つだけです。
- 取引先企業は、複数の下位取引先企業および下位取引先担当者を持つことができます。
アカウント管理は、企業間の顧客関係管理 (Dynamics 365) の重要な概念の 1 つです。これは、組織が他の会社に対して行っているすべてのアクティビティを表示する必要があるためです。 これらすべてのアクティビティは、アカウント レベルでまとめます。 Account テーブル参照を表示します。
連絡先テーブル
Dataverse では、連絡先は通常、顧客、サプライヤー、同僚などの関係を持つ部署の個人を表します。 連絡先テーブルは、他のほとんどのテーブルがリンクされているテーブルの 1 つです。 contact は、スタンドアロン テーブルになることができます。 この表には、プロフェッショナル、個人、家族の情報、および複数の住所が含まれています。 連絡先テーブル参照を表示します。
取引先企業も取引先担当者も顧客管理の一部であり、相互の関係は次のとおりです。
- contact は、account と contact 以外のすべてのテーブルの親になることができます。
- 1 つの取引先担当者の上位に存在できる取引先企業は 1 つだけです。
- 連絡先は、 Account.PrimaryContactId 列を設定するアカウントのプライマリ連絡先としてマークできます。
連絡先テーブルには、電子メール アドレス、番地、電話番号などの人物に関する情報が格納されます。 また、その人の誕生日や記念日など、その他の関連情報も含まれます。 顧客の全体像が見えるようにするには、部署が抱える顧客の種類に応じて、取引先担当者のみ、または取引先担当者と取引先企業の両方が必要になります。
アクティビティやメモなどのテーブルを contact テーブルにリンクすると、ユーザーは、ユーザーが顧客に対して行ったすべての通信、ユーザーが顧客に代わって実行したすべてのアクション、およびユーザーが顧客に関して必要とするすべての情報を確認できます。
CustomerAddress テーブル
この表には、顧客レコード (アカウントと連絡先) の住所と配送先の情報が含まれています。 既定では、Dataverse は、新しい顧客レコードが作成されるときに、これらのレコードのデータがない場合でも、このテーブルに少なくとも 2 つの customeraddress レコードを作成します。
この動作を変更する方法について説明します
取引先レコードと連絡先レコードに関連するすべての customeraddress レコードは、それぞれ Account_CustomerAddress 関係と Contact_CustomerAddress 関係を介して提供されています。 これらのリレーションシップはどちらも parentid 参照を使用し、 parentidtypecode 列は、住所が関連付けられている顧客レコードの種類を示します。
顧客レコードに埋め込まれた住所データ
顧客レコードを含む 2 つまたは 3 つの埋め込み customeraddress レコードのデータを取得または変更できます。
- アカウント レコードには、列
address1_addressidとaddress2_addressidがあります。 - 連絡先レコードには、
address1_addressid、address2_addressid、address3_addressidの列があります。
これらの列にはcustomeraddressid値が格納されています。また、address1*、address2*、またはaddress3*をプレフィックスとして持つ他の顧客の列があり、これらの列にはcustomeraddressテーブルからの対応するアドレス情報が含まれています。
customeraddress
addressnumber 列は、親顧客レコード列に適用される住所を示します。
addressnumber列を、同じ親顧客に関連する別のcustomeraddress レコードで使用される値に設定することはできません。 既存の addressnumber 値を 0 または null に設定し、顧客レコードのレコードの相対位置を入れ替える場合は、別のレコードの値を変更できます。
addressnumber値は、顧客レコード内のそれぞれの埋め込みアドレス位置 (1、2、または3) を制御する以外に、顧客用に作成された各レコードに対してインクリメントされますが、addressnumber列の値は他の目的には使用されません。
Dataverse は、customeraddress行を直接更新するのではなく、対応する顧客レコード列を介してのみこれらのcustomeraddressレコードを更新します。 ただし、誰でもこれらのレコードをcustomeraddressレコードとして編集したり、アカウントレコードや連絡先レコードに埋め込まれていないcustomeraddressレコードやaccountレコードに関連付けられたcontactレコードをさらに追加したりできます。
埋め込まれた顧客住所行の削除は許可されていません
既定では、顧客レコードのcustomeraddress、address1_addressid、またはaddress2_addressidで参照されている埋め込みaddress3_addressid レコードのいずれかを削除しようとすると、次のようなエラーが発生します。
名前:
CannotDeleteDueToAssociation
コード:0x80040227
数:-2147220953
メッセージ: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
空のレコードの作成を無効にする
customeraddress テーブルの各行は、支払う Dataverse 容量に対してカウントされるため、このコストを最小限に抑えることができます。
customeraddressの [空のアドレス レコードの作成を無効にする] 設定を変更することで、顧客レコードごとに空のテーブル行を作成しないように Dataverse に指示できます。 この動作を変更する前に、既定の動作に依存する既存のカスタマイズがあるかどうかを検討する必要があります。
この設定の詳細
この設定がオンになっている間は、新しい顧客レコードの作成時に新しい空の customeraddress テーブル行は作成されません。 レコードは、受信ペイロードにアドレス データが含まれている場合にのみ作成されます。 通常、ペイロードにはデータを含む列のみが含まれます。 列のデータがない場合、列はペイロードに含まれません。レコードの保存時に値は null になります。 ただし、ペイロードに値が null に設定されたアドレス列が含まれている場合、アドレスは null 値で作成されます。 空のレコードが作成されているのを引き続き確認する場合は、作成方法と、そのクライアント アプリケーションが null 値を持つ列データを送信しているかどうかを確認します。
[空のアドレス レコードの作成を無効にする] 設定をオフにすると、既定の動作が再開されます。 この設定を有効にしても、既存の customeraddress テーブル行は削除されません。 この設定をオフにした後にオンに戻しても、作成されなかったレコードは再作成されません。
空のアドレス レコードの作成が無効になっているかどうかを検出する
次の関数例は、環境内で [空のアドレス レコードの作成を無効にする ] 設定が有効になっているかどうかを検出する方法を示しています。
この静的 IsEmptyAddressRecordCreationDisabled メソッドでは、 WhoAmIRequest クラス と IOrganizationService.Retrieve メソッド を使用して 、Organization.OrgDbOrgSettings 列の値を確認します。
static bool IsEmptyAddressRecordCreationDisabled(IOrganizationService service)
{
Guid orgId = ((WhoAmIResponse)service
.Execute(new WhoAmIRequest())).OrganizationId;
Entity organization = service
.Retrieve("organization", orgId, new ColumnSet("orgdborgsettings"));
XDocument orgdborgsettings = XDocument
.Parse((string)organization["orgdborgsettings"]);
XElement? element = orgdborgsettings
.XPathSelectElement("//CreateOnlyNonEmptyAddressRecordsForEligibleEntities");
// Return true only when the element exists and has the value of 'true'
return element != null && element.Value == "true";
}
埋め込みアドレス レコードを削除する
既定では、顧客テーブルのcustomeraddress、address1_addressid、またはaddress2_addressid列によって参照される埋め込みaddress3_addressidテーブル行を削除することはできません。 「埋め込み顧客住所行の削除が許可されない」を参照してください
Power Platform 管理センターの [アドレス レコードの削除を有効にする] 設定では、この動作が変更されます。 この設定の詳細
アドレス レコードの削除が有効になっているかどうかを検出する
これらの関数例は、環境内で [アドレス レコードの削除を有効にする] 設定が有効になっているかどうかを検出する方法を示しています。
この静的IsDeleteAddressRecordsEnabled メソッドでは、WhoAmIRequest クラスと IOrganizationService.Retrieve メソッドを使用して、Organization.OrgDbOrgSettings 列の値を確認します。
static bool IsDeleteAddressRecordsEnabled(IOrganizationService service)
{
Guid orgId = ((WhoAmIResponse)service
.Execute(new WhoAmIRequest())).OrganizationId;
Entity organization = service
.Retrieve("organization", orgId, new ColumnSet("orgdborgsettings"));
XDocument orgdborgsettings = XDocument
.Parse((string)organization["orgdborgsettings"]);
XElement? element = orgdborgsettings
.XPathSelectElement("//EnableDeleteAddressRecords");
// Return true only when the element exists and has the value of 'true'
return element != null && element.Value == "true";
}
空の顧客住所レコードの一括削除
空のアドレス レコードの作成を無効にし、アドレス レコードの削除を有効にした後、次の例の関数を使用して、customeraddress メッセージを使用して空のBulkDelete レコードを非同期的に削除できます。
これらの関数は Address (CustomerAddress) の書き込み可能な列/属性 に基づいており、環境内にある可能性のあるカスタム列は含まれません。 カスタム列を含める必要がある場合は、これらのクエリを変更できます。
静的BulkDeleteEmptyCustomerAddressRecords メソッドは、customeradddressを使用して空の レコードを削除するシステム ジョブを作成します。
このメソッドでは、「IsDeleteAddressRecordsEnabledIsEmptyAddressRecordCreationDisabledする」 と「空のアドレス レコードの作成が無効になっているかどうかを検出する」で説明されている静的メソッドの例を使用して、これらの設定がすべての空の顧客アドレス レコードの削除を許可するように構成され、新しいアドレス レコードが作成されないようにします。
/// <summary>
/// Create a Bulk Delete job to delete empty customer address records
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance.</param>
/// <returns>The Id of the system job</returns>
/// <exception cref="Exception"></exception>
static Guid BulkDeleteEmptyCustomerAddressRecords(IOrganizationService service)
{
if (!IsDeleteAddressRecordsEnabled(service))
{
throw new Exception("Enable deletion of address records" +
" before running this method.");
}
if (!IsEmptyAddressRecordCreationDisabled(service))
{
throw new Exception("Disable empty address record creation" +
" before running this method.");
}
var query = new QueryExpression("customeraddress")
{
ColumnSet = new ColumnSet("customeraddressid"),
Criteria =
{
Conditions =
{
new ConditionExpression("city", ConditionOperator.Null),
new ConditionExpression("country", ConditionOperator.Null),
new ConditionExpression("county", ConditionOperator.Null),
new ConditionExpression("fax", ConditionOperator.Null),
new ConditionExpression("freighttermscode", ConditionOperator.Null),
new ConditionExpression("latitude", ConditionOperator.Null),
new ConditionExpression("line1", ConditionOperator.Null),
new ConditionExpression("line2", ConditionOperator.Null),
new ConditionExpression("line3", ConditionOperator.Null),
new ConditionExpression("longitude", ConditionOperator.Null),
new ConditionExpression("postalcode", ConditionOperator.Null),
new ConditionExpression("postofficebox", ConditionOperator.Null),
new ConditionExpression("primarycontactname", ConditionOperator.Null),
new ConditionExpression("shippingmethodcode", ConditionOperator.Null),
new ConditionExpression("stateorprovince", ConditionOperator.Null),
new ConditionExpression("telephone1", ConditionOperator.Null),
new ConditionExpression("telephone2", ConditionOperator.Null),
new ConditionExpression("telephone3", ConditionOperator.Null),
new ConditionExpression("upszone", ConditionOperator.Null),
new ConditionExpression("utcoffset", ConditionOperator.Null)
}
}
};
BulkDeleteRequest request = new()
{
QuerySet = new QueryExpression[] { query },
StartDateTime = DateTime.UtcNow,
RecurrencePattern = string.Empty,
SendEmailNotification = false,
JobName = "Delete empty customer address records",
ToRecipients = new List<Guid>().ToArray(),
CCRecipients = new List<Guid>().ToArray()
};
var response = (BulkDeleteResponse)service.Execute(request);
return response.JobId;
}