エンティティレコードの一括削除ジョブは BulkDeleteRequest メッセージを発行することで起動できます。BulkDeleteRequest のサンプルは下記のDynamics CRM 4.0 のページや Dynamics CRM SDK にも含まれます。

- BulkDelete Message
http://msdn.microsoft.com/en-us/library/cc155955.aspx

今回はエンティティのレコードを削除ではなく、フィルタ条件に該当するレコードのみを削除するサンプルを掲載します。

動作確認は、 Windows Server 2003 (.NET 3.5 SP1) 上で構築した Dynamics CRM 4.0 で行っています。

1. 作成する フィルタ付き一括削除ジョブ の内容

今回は、アプリケーション構成ファイルの appSettings セクションのキー importname で指定された文字列パターンに該当するインポート名のインポートレコードを削除するプログラムを作成します。

2. プログラムの作成

適当な名前でコンソールプログラムプロジェクトを起動します。sdkに付属するdll( microsoft.crm.sdk.dll と microsoft.crm.sdktypeproxy.dll ) を参照に追加します。既定で作成される Program.cs を次のように編集します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.Sdk.Query;
using System.Net;
using System.Configuration;

namespace ComponentGeek.FIlteredBulkDelete
{
    class Program
    {   // On-Premise 認証前提で作成しています
        static void Main(string[] args)
        {
            CrmService service = GetCrmService();
            DeleteEntityRecords(service);
        }

        /// <summary>
        /// 指定された名前空始まるインポートレコードを削除する
        /// </summary>
        /// <param name="service"></param>
        private static void DeleteEntityRecords(CrmService service)
        {
            BulkDeleteRequest request = new BulkDeleteRequest();
            request.JobName = "インポートデータの一括削除";

            // メールによる通知なし
            Guid[] emptyRecipants = new Guid[0];
            request.CCRecipients = emptyRecipants;
            request.ToRecipients = emptyRecipants;
            request.SendEmailNotification = false;
            request.RecurrencePattern = string.Empty;
            request.StartDateTime = CrmDateTime.Now;

            // 条件設定
            QueryExpression query = new QueryExpression("importfile");
            query.ColumnSet = new ColumnSet();
            query.ColumnSet.AddColumn("importfileid");

            ConditionExpression condition = new ConditionExpression("name", ConditionOperator.Like, new object[] { ImportName });
            query.Criteria.AddCondition(condition);
            condition = new ConditionExpression("statecode", ConditionOperator.Equal, new object[] { ImportState.Active.ToString() });
            query.Criteria.AddCondition(condition);

            request.QuerySet = new QueryBase[] { query };

            BulkDeleteResponse response = service.Execute(request) as BulkDeleteResponse;
        }
        private static CrmService GetCrmService()
        {

            CrmAuthenticationToken token = new CrmAuthenticationToken();
            token.AuthenticationType = 0;
            token.OrganizationName = OrgName;

            CrmService service = new CrmService();

            UriBuilder uriBuilder = new UriBuilder();
            uriBuilder.Scheme = HttpScheme;
            uriBuilder.Host = HostName;
            uriBuilder.Port = Port;
            uriBuilder.Path = "/mscrmservices/2007/crmservice.asmx";
            service.Url = uriBuilder.Uri.ToString();
            service.CrmAuthenticationTokenValue = token;
            service.Credentials = CredentialCache.DefaultCredentials;
            service.UseDefaultCredentials = true;
            service.Timeout = 100000;

            service.PreAuthenticate = true;
            service.UnsafeAuthenticatedConnectionSharing = true;

            return service;
        }
        /// <summary>
        /// HTTPスキーム
        /// </summary>
        static string HttpScheme
        {
            get
            {
                string scheme = ConfigurationManager.AppSettings["scheme"];
                if (string.IsNullOrEmpty(scheme))
                {
                    scheme = "http";
                }
                return scheme;
            }
        }
        /// <summary>
        /// ホスト名
        /// </summary>
        static string HostName
        {
            get
            {
                string hostname = ConfigurationManager.AppSettings["hostname"];
                if (string.IsNullOrEmpty(hostname))
                {
                    hostname = "localhost";
                }
                return hostname;
            }
        }
        /// <summary>
        /// ポート
        /// </summary>
        static int Port
        {
            get
            {
                string sPort = ConfigurationManager.AppSettings["port"];
                if (string.IsNullOrEmpty(sPort))
                {
                    sPort = "80";
                }
                return int.Parse(sPort);
            }
        }
        /// <summary>
        /// 組織名
        /// </summary>
        static string OrgName
        {
            get
            {
                string orgname = ConfigurationManager.AppSettings["orgname"];
                if (string.IsNullOrEmpty(orgname))
                {
                    orgname = "dyn";
                }
                return orgname;
            }
        }
        /// <summary>
        /// インポートの名前
        /// </summary>
        static string ImportName
        {
            get
            {
                string importname = ConfigurationManager.AppSettings["importname"];
                if (string.IsNullOrEmpty(importname))
                {
                    throw new InvalidOperationException("importnameを指定してください");
                }
                return importname;
            }
        }

    }
}

 

3. まとめ

今回の説明は以上です。一括削除ジョブは、フィルタ条件を設定することで柔軟にエンティティのれこー^度を一括削除できるようになります。

が、一括削除ジョブ自体は高速に削除を行う処理ではないので、その場合はカスタムでプログラムを作成する必要があります。