Morning Girl

Web API, Windows, C#, .NET, Dynamics 365/CRM etc..

【C#】【Dynamics CRM】PluginのContextを用いた関連レコードの作成

個人的にPluginのよくあるパターンとして、CreateMessageに設定して、作成されるレコードに関連づいたレコードを作成する、というものがある気がします。

もちろん、ワークフローでも可能なアプローチですが、例えば一括で複数件の関連レコードを作成する、マスタの情報も参照しつつ複合的な関連付けを試みる、などになりますと、Pluginで作成するぐらいしかアプローチは無いと思います。

環境

Dynamics CRM 2015(7.0)

Dynamics CRM SDK 2015(7.0.1)

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);

        }
    }
}

実行結果

f:id:sugimomoto:20150413141150p:plain