Morning Girl

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

【C#】【Dynamics CRM】PluginにおけるPre・PostEntityImagesの利用

Dynamics CRM Pluginでは、例えばUpdateに登録したPluginの場合、ContextのInputParameterに送られてくるデータは更新されたデータのみになります。

しかしながら、シナリオによってはUpdateする前の値と比較し何かしらの処理を行いたい、もしくはUpdate後のデータを考慮したい、といった場合もあると思います。

それを実現する機能がPluginの【PreEntityImaqges】と【PostEntityImages】になります。

Pre・PostEntityImagesの概要

Pre・PostEntityImageはそれぞれのPluginのStepに登録することによって、Messgae処理の前後の情報をPlugin内で使用することができます。

Pre・PostEntityImageは下記MSDNにある通り、特定のRequestのみで使用できます。 (Create・Delete・Updateなど基本的なものはサポートしています。)

MSDN-Pre and Post Entity Images https://msdn.microsoft.com/en-us/library/gg309673.aspx#bkmk_preandpost

取得できるイメージ(EntityなのかIdなのか)もPropertyに記載されていますので、実装するPluginのMessageがサポートされているかどうか、確認しておく必要があります。

またPre・PostEntityImagesを扱う注意点は以下の様な感じです。

・PostEntityImagesは Post-operationのSynchronousまたはAsynchronousでしか利用できない。

・CreateRequestでは、PreEntityImagesをサポートしない。(そもそもPreが存在しない)

・DeleteRequestでは、PostEntityImageをサポートしない。(これももちろん存在しない)

Pluginへの設定方法

Pre・PostEentityImagesの登録方法は以下のとおりです。

1.Plugin Registration Toolにて、Imageを付与する対象となるStepを選択。

2.右クリックメニューにて[Register new Image]を選択。

f:id:sugimomoto:20150414135457p:plain

3.新しくImageを作成する画面が開くので、Imageに関する情報を入力。

f:id:sugimomoto:20150414135515p:plain

・Image Type:[Pre][Post]付与するものをチェック。

・Name:Imageの名前。任意

・Entity Alias:パラメータを取得する際のコレクションKey名。

・Parameters:取得できる対象フィールド。初期状態はすべてのフィールドが対象。

f:id:sugimomoto:20150414135527p:plain

以上でPre・PostEntityImageを付与することが可能です。

取得する場合は下記の通り、ContextからPreEntityImagesまたはPostEntityImagesプロパティを選び、KeyにEntity Alias名を入力します。

var PreEntityImage = (Entity)context.PreEntityImages["EntityAlias"];

var PostEntityImage = (Entity)context.PostEntityImages["EntityAlias"];

取得されてくるデータの比較。

今回は以下の様なPluginを作成、デバックしデータの中身を比較してみました。

Pluginの設定は以下のとおりです。

/// Massege : update
/// Primary Entity : account
/// Secondary Entity : none
/// Run is User's Context : Calling User
/// Execution Order : 1
/// Stage : Post-operation
/// Execution Mode : Synchronous
using System;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;

namespace MyProject.Plugin
{
    public class PrePostEntityImage : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            var PreEntityImage = (Entity)context.PreEntityImages["EntityAlias"];

            var PostEntityImage = (Entity)context.PostEntityImages["EntityAlias"];

            var InputParameter = (Entity)context.InputParameters["Target"];

            throw new InvalidPluginExecutionException();
        }
    }
}

実行結果

今回はあらかじめ名前だけ登録したAccountレコードに、フリガナを追記してUpdateを起こしました。

f:id:sugimomoto:20150414135609p:plain

■InputParameter

フリガナの情報と修正日、修正者の情報などが入ってきているのがわかります。

f:id:sugimomoto:20150414135942p:plain

■PreEntityImages

Preは変更前のレコード情報のため、フリガナは入ってきていません。

しかし、InputParameterには含まれていなかったNameや、Optionsetなど既定でデータが入力されているものが入っているのがわかります。

f:id:sugimomoto:20150414140044p:plain

■PostEntityImages

PreEntityImagesの情報に比べ、フリガナの情報が追加されていることがわかります。

f:id:sugimomoto:20150414140105p:plain

終わりに

試したことはありませんが、Pre・PoseEntityImagesを利用することで、単純にRetrieveなどでデータを取得してくるよりもパフォーマンスが優れるようです。

Pluginは2分間の処理制限もありますし、このようなところでも細かなパフォーマンス・チューニングは結構大事になるところかもしれません。