Dynamics CRM 2011 Developer Extensions 紹介 – CrmOrganizationServiceContext のキャッシュ機能

みなさん、こんにちは。

今年も World Partner Conference の時期になりました。Microsoft Dynamics
CRM と Office 365 や Windows Azure に関する重要な情報が日々提供されて
いますので、参加されていらっしゃらない方は、是非 Web をご覧ください。

WPC2012 については後日追ってブログでも紹介します。

さて今回は CrmOrganizationServiceContext クラスの紹介をします。SDK で
提供されるサービスクラスの中でも、もっとも機能が充実したクラスです。

CrmOrganizationServiceContext クラス概要

SDK には以下の定義があります。

public class CrmOrganizationServiceContext :
OrganizationServiceContext, IInitializable, IOrganizationService,
IUpdatable, IExpandProvider, IOrganizationServiceContainer

つまり、OrganizationServiceContext や IOrganizationService を継承する他、
IUpdatable、IExpandProvider を継承するため、独自の WCF サービスの
開発に利用可能になります。

そのほかにもいくつか機能がありますが、今回はその中でもキャッシュの
機能を紹介します。

キャッシュ機能の確認

このサンプルでは CrmSvcUtil.exe ツールを利用して作成したクラスを
利用します。こちらの記事に沿って、CrmOrganizationServiceContext 用の
GeneratedCodeforCrmOrganizationServiceContext.cs ファイルを生成してください。

1. Visual Studio 2010 を開きます。

2. 新しいプロジェクトリンクをクリックし、コンソールアプリケーションを作成します。
名前に “MyConsoleApplication” と入力して、OK ボタンをクリックします。

3. 作成された MyConsoleApplication プロジェクトを右クリックして、プロパティを
クリックします。

4. 対象のフレームワークより “.NET Framework 4” を選択します。ポップアップが
出るので、はいボタンをクリックします。

5. MyConsoleApplication プロジェクトを右クリックして、 追加 | 既存の項目を
クリックします。

6. 生成したGeneratedCodeforCrmOrganizationServiceContext.cs ファイルを
選択し、追加ボタンをクリックします。このファイルは既に MyConsoleApplication
名前空間を持っています。

7. 以下の参照を追加します。
Microsoft.Xrm.Sdk.dll
Microsoft.Xrm.Client.dll
System.Runtime.Serialization
System.Data.Services
System.Data.Services.Client
System.Configuration

8. app.config ファイルを開き、以下の内容と差し替えます。また connectionString を
環境によって変更してください。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="microsoft.xrm.client" type="Microsoft.Xrm.Client.Configuration.CrmSection, Microsoft.Xrm.Client"/>
</configSections>
<connectionStrings>
<add name="Xrm" connectionString="Server=https://crm2011srv:5555/CRM; Domain=CONTOSO; Username=administrator; Password=password" />
</connectionStrings>
<microsoft.xrm.client>
<contexts>
<add name="Xrm" type="MyConsoleApplication.XrmContext, MyConsoleApplication" connectionStringName="Xrm"/>
</contexts>
</microsoft.xrm.client>
</configuration>

9. Program.cs ファイルを開き、Main メソッド内に以下のコードを追加します。

var connection = new CrmConnection("Xrm");
var xrm = new XrmContext(connection);

10. 続いて以下のコードを追加します。

// 既存の取引先企業の表示
DisplayExistingAccounts(xrm);

// 新規カスタムエンティティのレコード作成
var mycustom = new new_mycustomentity
{
new_name = "Sample Custom Entity 0"
};

// カスタムエンティティと紐付く取引先企業レコードの作成
var myaccount = new Account
{
Name = "Sample Account 01",
EMailAddress1 = "sampleaccount@sample.test",
new_new_mycustomentity_account = mycustom
};

xrm.AddObject(myaccount);
xrm.SaveChanges();

// 再び既存の取引先企業の表示
DisplayExistingAccounts(xrm);

Console.WriteLine("Add Account Record via IE and press any key to continue.");
Console.ReadKey();

// キャッシュ動作確認のため再表示
DisplayExistingAccounts(xrm);

Console.WriteLine("Press any key to exit.");
Console.ReadKey();

11. DisplayExistingAccounts メソッドを追加します。

private static void DisplayExistingAccounts(XrmContext xrm)
{
// メールアドレスが @sample.test の取引先企業を取得
var myAccounts = xrm.AccountSet
.Where(a => a.EMailAddress1.EndsWith("@sample.test"));

// 取引先企業の表示
foreach (var account in myAccounts)
{
Console.WriteLine(account.Name);
}
Console.WriteLine("---------------------------");
}

12. F5 キーを押下して、アプリケーションを実行します。まず初めに現在の
取引先企業で、メールアドレスが @sample.text で終わるレコードの
一覧が表示されます。その後続いてプログラム内で追加されたレコードが
表示されます。そこでいったんプログラムが停止します。

13. 次に Internet Explorer より Microsoft Dynamics CRM に接続し、取引先
企業レコードを 1 件追加します。この時、メールアドレスが @sample.text で
終わる用にしてください。

14. プログラムに戻って、任意のキーを押下します。プログラムは実行され
ますが、Internet Explorer から追加したレコードが表示されません。

キャッシュ機能の概要

上記サンプルアプリケーションでわかるように、サービスコンテキストを
利用してレコードを追加した場合には、最新の情報を取得しますが、他の
場所、例えば Internet Explorer からレコードを追加した場合は、最新の
レコードを取得しません。サービスコンテキストでキャッシュ機能が有効で
あり、前回クエリを実行してから変更がないと判断したため、実際には
クエリを実行せず、前回の実行結果を再利用するためです。

まとめ

キャッシュ機能を利用することで、マスタ系のデータについては無駄な
クエリ発行を抑制することが可能ですが、その一方でデータを他の場所
から追加した場合には、最新の情報が表示されません。

次回はこの問題を解消するため、キャッシュ機能をコントロールする
方法を紹介します。

- Dynamics CRM サポート 中村 憲一郎