【C#】【Dynamics CRM】PluginのContextを用いた関連レコードの作成
個人的にPluginのよくあるパターンとして、CreateMessageに設定して、作成されるレコードに関連づいたレコードを作成する、というものがある気がします。
もちろん、ワークフローでも可能なアプローチですが、例えば一括で複数件の関連レコードを作成する、マスタの情報も参照しつつ複合的な関連付けを試みる、などになりますと、Pluginで作成するぐらいしかアプローチは無いと思います。
環境
Dynamics CRM 2015(7.0)
Plugin概要
今回はAccount(取引先企業)が作成された際、関連づくContact(取引先担当者)レコードを作成するPluginを作成してみました。
関連付けレコードを作成する際の注意点
CreateMessgaeにより作成されたレコードへ関連付ける際、1つの注意点となるのが、Pluginのステージと同期・非同期設定です。
今回の例では、前回説明したContext情報に存在しているCreateされる予定のレコードGUID値を元に、関連付けを設定します。
しかしながら、Pluginのステージによっては、実行処理中にまだCreateMessageによって生成される予定のレコードが作成されていない(Lookupで参照できない)状態のものがあります。
例えば、20:Pre-Operation:Synchronousで上記Pluginを実現する場合、まだCreateResponseが到着していない(レコードが作成されていない)状態にあるため、単純なIOrganizationServiceによるCreate処理では、関連付けレコードを作成することができません。 (後続のPluginに処理を行わせるないし、Asynchronousで実行するなどの方法を取る必要があります)
PluginStep設定値
/// Massege : create
/// Primary Entity : account
/// Secondary Entity : none
/// Run is User's Context : Calling User
/// Execution Order : 1
/// Stage : Post-operation
/// Execution Mode : Synchronous
コード
今回はOutputParameterに含まれるGUIDを元に関連付けを行いました。
InputParameterのTargetにもCreateで設定されるGUIDは含まれていますので、そちらで実行しても問題無いと思います。
using System; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; namespace MyProject.Plugin { public class CreateAssciateContact : IPlugin { public void Execute(IServiceProvider serviceProvider) { var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); var factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); // IOrganizationService の作成 var service = (IOrganizationService)factory.CreateOrganizationService(context.UserId); // CreateResponse のGuidが存在しない場合、Pluginの処理を終了。 if (!context.InputParameters.Contains("id") || !(context.InputParameters["id"] is Guid)) return; // OutputParameterからCreateResponseのGuidを抽出 var accountId = (Guid)context.OutputParameters["id"]; var contact = new Entity("contact"); contact["lastname"] = "contact ver : "; contact["firstname"] = accountId.ToString(); // GuidとPlucinContextの実行エンティティ名を元に、EntityReferenceを作成 contact["parentcustomerid"] = new EntityReference() { LogicalName = context.PrimaryEntityName, Id = accountId }; // 関連づくContactレコードを作成 service.Create(contact); } } }
実行結果