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 を設定するようにします。
さんのコメント: さんのコメント: