Dynamics CRM の Entity データを検索する方法として、次の方法がサポートされます。

  • CrmService クラスを使用してWebサービスごしにデータを検索する
  • フィルターされたEntityのビューを検索する

Webサービス呼び出しより、データベースに接続した検索のほうが圧倒的に高速で自由度があります。データベースに直接接続できる場合は、フィルターされたEntityのビューを使用したほうが、パフォーマンスが高くなります。

今回は、Filtered ビューを使用してみます。

動作確認は、一つのPC上で構築したDynamics CRM 4.0 と SQL Server 2005 Developer Edition を使用して行っています。

1. FilteredView を使用する

各Entityのフィルターされたビューの名前は Filtered + Entityの論理名 となります。systemuser エンティティのフィルタされたビュー名は、dbo.FilteredSystemUser となります。

フィルターされたビューを検索することはサポートされていますが、EntityのデータをSQL を使用して更新することはノンサポートなので、注意してください。

下記の例はsystemuser を検索するサンプルと、systemuser のロール名一覧を取得するサンプルです。

-- CRMの組織のデータベース
USE testorg_MSCRM
GO
-- ユーザアカウント、ロール名、部署名を取得
    select systemuser.domainname, role.name, systemuser.businessunitidname
      from dbo.FilteredSystemUser systemuser
inner join dbo.FilteredSystemUserRoles systemuserroles
        on systemuser.systemuserid = systemuserroles.systemuserid
inner join dbo.FilteredRole role
        on  systemuserroles.roleid = role.roleid

実行結果は、接続ユーザのCRM上の権限により異なります。CRMのユーザ出なかったり、割り当てられているCRMのセキュリティーロールにsystemuser Entity を検索する権限がない場合、検索結果は0件となります。これは、フィルタ付きビュー内で、クエリ実行ユーザのCRM上の権限が適用されるためです。

クエリを実行しているユーザの権限を現在のセッションのユーザ以外のユーザとしたい場合は、CONTEXT_INFO を使用します。

2. CONTEXT_INFOを使用する

IFD構成の場合に、カスタムアプリをCRMに統合していると、現在接続しているユーザのコンテキストで、Entityデータを検索した結果を取得したい場合があります。クエリ実行時に、DBへの接続しているユーザではなく、CRM上の特定ユーザのセキュリティーロールの権限でフィルタされたビューを検索した結果を取得したい場合、CONTEXT_INFOにCRMユーザのコンテキスト情報systemuser.systemuserid を設定します。CONTEXT_INFOを設定することで、特定のCRMユーザの権限でフィルタ付きのビューを検索した結果と同じ結果を得たることができます。

CONTEXT_INFOを設定する理由は、各フィルターされたEntityビューの定義で使用されtれいる、fn_FindUserGuid スカラ関数の実装方法を確認することでCONTEXT_INFO が使用されていることから確認できます。

ADO.NET からSQLを実行する場合や、SQL Server Management Studio からクエリを実行する場合に、次のサンプルにあるようにCONTEXT_INFOを設定して実行します。CONTEXT_INFOを使用することで、クエリ実効ユーザコンテキストがCONTEXT_INFOのユーザのものとなり、CRM上のセキュリティロールの権限に従う、フィルタされたビュー検索結果を取得できます。

-- CRM接続ユーザのコンテキストを切り替える
-- CONTEXT_INFO()で表されるユーザのCRMセキュリティー
-- ロールの権限によってクエリが実行されます。
DECLARE @__context_info varbinary(128)
DECLARE @__systemuserid uniqueidentifier
-- クエリ実行ユーザコンテキストとして使用するsystemuser.systemuserid
SET @__systemuserid = N'F1A7CF2E-1915-DE11-A3CA-0003FFBF2D57'
SET @__context_info = cast(@__systemuserid as varbinary(128))
SET CONTEXT_INFO @__context_info


    select systemuser.systemuserid, systemuser.domainname, role.name
      from dbo.FilteredSystemUser systemuser
inner join dbo.FilteredSystemUserRoles systemuserroles
        on systemuser.systemuserid = systemuserroles.systemuserid
inner join dbo.FilteredRole role
        on  systemuserroles.roleid = role.roleid

GUID を設定するのはもっと簡単に記述できます。(2010/04/10追記)

DECLARE @userid uniqueidentifier
SET @userid = 'XXXXXXXXX' -- GUID 文字列
SET CONTEXT_INFO @userid

3. まとめ

今回の説明は以上です。CrmService を使用した検索より、フィルタされたEntityビューを検索するほうがはるかに高速に検索処理を行えますので、直接DBに接続できる場合は、後者を使用するほうがよいです。実行するCRM上のユーザコンテキストを切り替えたい場合は、CONTEXT_INFOに切り替えるユーザのsystemuser.systemuserid を設定するようにします。