みなさん、こんにちは。
今回は Dynamics CRM Online 2015 Update 1 で提供されるプラット
フォームと SDK の新機能より、変更されたレコードの一括取得に
ついて紹介します。
概要
Dynamics CRM 上のレコードをマスターとして外部システムと連携
する場合、前回取得したデータセットからの差分のみを取得すべき
ですが、これまではそのような機能が提供されていませんでした。
※メタデータの差分取得は提供済み
このような要望を満たすため、今回のリリースではレコードの差分
取得がサポートされます。
動作確認
今回は取引先企業データを外部に連携するシナリオを考えます。
プログラムの作成
1. Visual Studio を起動します。新しいプロジェクトをクリック
して、Visual C# | Windows デスクトップ | コンソールアプリ
ケーションを選択します。.NET Framework 4.5.2 を指定します。
任意の名前を付けて、「OK」をクリックします。
![image image]()
2. ソリューションエクスプローラーより作成したプロジェクトを
右クリックして、NuGet パッケージの管理をクリックします。
![image image]()
3. 左ペインで「オンライン」を選択後、右上の検索ボックスにて
crmsdk を検索します。一覧より Microsoft Dynamics CRM 2015
SDK client and portal assemblies を選択して、「インストール」を
クリックします。
![image image]()
4. インストールが完了したら「閉じる」で NuGet パッケージの
管理を閉じます。
5. Main メソッドに以下のコードを追加します。これで Dynamics
CRM 組織への接続が作成できます。接続文字は適宜変更します。
CrmConnection conn = CrmConnection.Parse("Url=https://contoso.crm.dynamics.com; Username=someone@contoso.onmicrosoft.com; Password=password;");
OrganizationService service = new OrganizationService(conn);
6. 差分取得時に渡すトークンを格納する文字列型変数を定義します。
また取得したデータを格納するリストを定義します。
string token;
List<Entity> initialrecords = new List<Entity>();
7. 以下のコードを追加して、既存の取引先企業を取得します。
// 差分要求の作成
RetrieveEntityChangesRequest request = new RetrieveEntityChangesRequest();
// クエリの指定
request.EntityName = "account";
request.Columns = new ColumnSet("name");
// ページングの指定
request.PageInfo = new PagingInfo() { Count = 5000, PageNumber = 1, ReturnTotalRecordCount = false };
8. 以下のコードを追加してデータを取得します。尚、既定で
一度の要求で取得できるレコード数が 5000 件のため while
ループでページングします。RetrieveEntityChangesResponse
の EntityChanges には追加/更新されたレコードと削除された
レコードの情報が含まれます。以下のコードは初回実行時と
想定しているため、追加/更新のみを確認しています。
while (true)
{
// 差分データの取得
RetrieveEntityChangesResponse response = (RetrieveEntityChangesResponse)service.Execute(request);
// 取得したデータをリストに保存
initialrecords.AddRange(response.EntityChanges.Changes.Select(x => (x as NewOrUpdatedItem).NewOrUpdatedEntity).ToArray());
// ページングが完了したら、次回差分取得のためのトークンを確保
if (!response.EntityChanges.MoreRecords)
{
token = response.EntityChanges.DataToken;
break;
}
// まだレコードがある場合はページング処理
request.PageInfo.PageNumber++;
request.PageInfo.PagingCookie = response.EntityChanges.PagingCookie;
}
initialrecords.ForEach(x => Console.WriteLine("Record {0} added", x["name"]));
Console.Read();
9. 次に差分取得のコードを追加します。利用するクエリは同じですが、
DataVersion に前回取得したトークンを指定しています。また今回は
差分取得しているため、削除されたレコードも確認しています。削除
されたレコードは Guid しかデータが無いため、EntityReference 型と
なります。
RetrieveEntityChangesRequest changerequest = new RetrieveEntityChangesRequest();
changerequest.EntityName = "account";
changerequest.Columns = new ColumnSet("name", "accountnumber", "telephone1");
changerequest.PageInfo = new PagingInfo() { Count = 5000, PageNumber = 1, ReturnTotalRecordCount = false };
// 前回取得したトークンを指定
changerequest.DataVersion = token;
// 追加/更新したレコードのリストを作成
List<Entity> neworupdatedrecords = new List<Entity>();
// 削除されたレコードのリストを作成
List<EntityReference> removedrecords = new List<EntityReference>();
while (true)
{
RetrieveEntityChangesResponse response = (RetrieveEntityChangesResponse)service.Execute(changerequest);
// 結果より追加/更新されたものだけを処理
neworupdatedrecords.AddRange(response.EntityChanges.Changes.Where(x=>x.Type == ChangeType.NewOrUpdated).Select(x => (x as NewOrUpdatedItem).NewOrUpdatedEntity).ToArray());
// 結果より削除されたものだけを処理
removedrecords.AddRange(response.EntityChanges.Changes.Where(x=>x.Type == ChangeType.RemoveOrDeleted).Select(x => (x as RemovedOrDeletedItem).RemovedItem).ToArray());
if (!response.EntityChanges.MoreRecords)
{
token = response.EntityChanges.DataToken;
break;
}
// ページング処理
request.PageInfo.PageNumber++;
request.PageInfo.PagingCookie = response.EntityChanges.PagingCookie;
}
neworupdatedrecords.ForEach(x => Console.WriteLine("Record {0} added or updated", x["name"]));
removedrecords.ForEach(x => Console.WriteLine("Record {0} removed", x.Id));
Console.Read();
プログラムの実行
1. F5 キーを押下してプログラムを実行します。
2. データの結果を確認します。
![image image]()
3. プログラムをそのままにして、ブラウザからレコードの追加
更新と削除を行います。今回は「テスト取引先企業」の追加、
「フォース コーヒー」の変更、「リビングウェア」の削除を
行いました。
4. プログラムに戻って Enter キーを押下します。意図した結果
になることを確認します。
![image image]()
まとめ
変更されたレコードの一括取得を行うことで、効率的にデータ
同期を行えます。尚、特定のレコードが前回取得以降に複数回
更新された場合も、詳細の履歴はわからず、最新の情報だけが
取得できます。
是非お試しください。
- 中村 憲一郎