エンティティレコードの一括削除ジョブは 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. まとめ
今回の説明は以上です。一括削除ジョブは、フィルタ条件を設定することで柔軟にエンティティのれこー^度を一括削除できるようになります。
が、一括削除ジョブ自体は高速に削除を行う処理ではないので、その場合はカスタムでプログラムを作成する必要があります。