OrganizationServiceContext の使用

注意

Effective November 2020:

  • Common Data Service has been renamed to Microsoft Dataverse. Learn more
  • Some terminology in Microsoft Dataverse has been updated. For example, entity is now table and field is now column. Learn more

This article will be updated soon to reflect the latest terminology.

Common Data Service では、 IOrganizationService インターフェイスを実装する数個のクラスを使用して、Web サービスにアクセスできます。 または、コード生成ツールで生成された OrganizationServiceContext を使用して、追加機能にアクセスできます。 OrganizationServiceContext クラスにより、変更を追跡し、ID およびリレーションシップを管理し、 LINQ プロバイダーにアクセスすることができます。 また、このクラスにはコンテキストが追跡するデータに対する変更の送信に使用する、OrganizationServiceContextSaveChanges() メソッドも含まれています。 このクラスは、 Windows Communication Foundation (WCF) データ サービスの DataServiceContext クラスと同じ概念に基づいています。

このクラスを生成するには、事前バインドの型を生成するときに /serviceContextName パラメーターの値を指定します。 コード生成ツールでは、この名前が生成したクラスの名前として使用されます。 コード生成ツールの使用方法に関する詳細については、「組織サービスを使用して事前バインド プログラミングのクラスを生成す」を参照してください。 アプリケーション、プラグイン、およびワークフロー活動を開発する際に、組織サービス コンテキストを使用できます。

OrganizationServiceContext クラスの使用方法

コンテキスト クラスのインスタンスを作成するには、クラス コンストラクターに IOrganizationService インターフェイスを実装するオブジェクトを渡す必要があります。 1 つの方法として、CrmServiceClient クラスのインスタンスを渡すことができます。 IOrganizationService インターフェイスの詳細については、「組織で IOrganizationService インターフェイスを使用する」を参照してください。

次のコード例は、コンテキスト クラスの新しいインスタンスを作成する方法を示しています。 この例では、コード生成ツールで /serviceContextName パラメーターを使用して名前を指定することによって、コンテキスト クラスに AdventureWorksCycleServiceContext という名前が付けられています。

//For early bound types to work correctly, they have to be enabled on the proxy.  
_serviceProxy.EnableProxyTypes();  
AdventureWorksCycleServiceContext context = new AdventureWorksCycleServiceContext(svc);  

組織サービス コンテキスト オブジェクトを作成すれば、エンティティの作成、変更、または削除の追跡を開始できます。

組織サービス コンテキストは Common Data Service への送信対象となるあらゆるエンティティまたは関連付けを追跡する必要があります。 たとえば、LINQ クエリでレコードを取得してコンテキストでエンティティが追跡されるようにするか、OrganizationServiceContext.Attach(Entity) メソッドを使用してコンテキストによるエンティティの追跡を開始することができます。 クライアント アプリケーションのデータを使用し、新しいエンティティの作成、関連エンティティの作成、既存のエンティティの変更を行うことができますが、変更を Common Data Service にコミットするには追跡対象のエンティティで SaveChanges メソッドを呼び出す必要があります。

変更の追跡

コンテキストによるエンティティの追跡方法を調べるには、エンティティ インスタンスの EntityState プロパティを確認します。 さまざまなメソッドを呼び出すか、LINQ クエリを使用して、Common Data Service のエンティティを追跡するように組織サービス コンテキストに通知する必要があります。 LINQ クエリから返されるすべてのエンティティはサービス コンテキストによって追跡されます。

サービス コンテキストにオブジェクトを追加するには、OrganizationServiceContext で次のいずれかのメソッドを呼び出します。

方法 用途
AddObject(Entity) 組織サービス コンテキストが追跡するエンティティ セットにエンティティを追加します。 コンテキスト内のエンティティの状態は Created に設定されます。 SaveChanges() メソッドを呼び出すと、このレコードが作成されるか、またはサーバーに追加されます。
Attach(Entity) 組織サービス コンテキストが追跡するエンティティ セットにエンティティを追加します。 コンテキスト内のエンティティの状態は Unchanged に設定されます。 SaveChanges() メソッドを呼び出しても、このエンティティは状態が変更されるまでサーバーに送信されません。
CreateQuery(String) 組織サービス コンテキストが追跡するエンティティ セットにクエリの結果を追加します。

Common Data Service では、組織サービス コンテキストでエンティティ間の関連付けを作成および更新できます。 CrmSvcUtil.exe ツールで生成され、事前バインド クラスに配置されるナビゲーション プロパティで、関連エンティティのプロパティや関連付けへのアクセスや変更を行うことができます。 関連エンティティをサーバーで更新できるようにするには、組織サービス コンテキストで関連エンティティを追跡する必要があります。

関連エンティティを操作する場合、およびサービス コンテキストにエンティティを追加する場合は、OrganizationServiceContext で次のメソッドを使用します。

方法 用途
AddRelatedObject(Entity, Relationship, Entity) コンテキストにターゲットを追加します。 ターゲット エンティティに対して Attach(Entity) メソッドを呼び出し、ソース エンティティとターゲット (関連) エンティティ間の AddLink(Entity, Relationship, Entity) メソッドを呼び出します。
AttachLink(Entity, Relationship, Entity) 追跡を行うコンテキストに関連エンティティを追加します。 コンテキスト内のエンティティの状態は Unchanged に設定されます。
AddLink(Entity, Relationship, Entity) ソース エンティティとターゲット エンティティ間の関連付けを作成します。 コンテキストにターゲットを追加します。 コンテキスト内のターゲット エンティティの状態は Created に設定されます。
LoadProperty(Entity, String) 指定した関連付けの関連エンティティ セットを読み込みます。 ナビゲーション プロパティを使用して関連エンティティにアクセスできるようになります。 親エンティティでナビゲーション プロパティを使用してエンティティにアクセスした後、関連エンティティで AddObject(Entity) メソッドを呼び出します。
UpdateObject(Entity) OrganizationServiceContext 内の指定したエンティティの状態が Modified に変更されます。
DeleteObject(Entity) OrganizationServiceContext 内の指定したエンティティの状態が Deleted に変更されます。

LINQ を使用して取得したエンティティの関連エンティティは、LoadProperty(Entity, Relationship) を使用してそれらを取得するまでは null です。 次のサンプル コードは、特定の取引先担当者レコードに関連付けられているタスク レコードにアクセスする方法を示しています。

Contact pam = context.ContactSet.Where(c => c.FirstName == "Pamela").FirstOrDefault();  
if (pam != null)  
{  
// pam.Contact_Tasks is null until you use LoadProperty  
    context.LoadProperty(pam, "Contact_Tasks");  
    Task firstTask = pam.Contact_Tasks.FirstOrDefault();  
}  

AddLink(Entity, Relationship, Entity) メソッドを使用して、関連付けを作成できます。 新しいリンク情報によってサーバーが更新される前に、SaveChanges() メソッドを呼び出す必要があります。

次のコード例は、取引先担当者と取引先企業の間に関連付けを作成する方法を示しています。

Relationship relationship = new Relationship("account_primary_contact");  
context.AddLink(contact, relationship, account);  
context.SaveChanges();  

変更の保存

組織サービス コンテキストは追跡中のエンティティのグラフを保持します。 組織サービス コンテキストがエンティティの変更を処理し、サーバーに送信する順序が重要です。 主エンティティの更新が処理された後に関連エンティティが処理されます。 関連エンティティによって主エンティティに値が設定されると、その値がサーバーでのデータの更新時に使用されます。

エンティティ情報が保存されるときにエラーが発生する場合、SaveChangesResult を含む新しい例外タイプが OrganizationServiceContext.SaveChanges() メソッドによりスローされます (メソッドに渡される SaveChangesOptions パラメーターの値にかかわらず)。

コンテキストが変更された場合の仮想メソッドの使用

場合によっては、OrganizationServiceContext の変更に基づいて操作を実行する必要があります。 この処理を簡素化するために、操作をインターセプトしたり、操作の通知を受けることができる仮想メソッドが用意されています。 仮想メソッドを利用するには、OrganizationServiceContext を継承するか、生成された組織サービス コンテキストを変更する必要があります。仮想メソッドの一覧を次の表に示します。

方法 説明
OnBeginEntityTracking(Entity) エンティティを OrganizationServiceContext にアタッチした後に呼び出します。
OnBeginLinkTracking(Entity, Relationship, Entity) リンクを OrganizationServiceContext にアタッチした後に呼び出します。
OnEndEntityTracking(Entity) エンティティを OrganizationServiceContext からデタッチした後に呼び出します。
OnEndEntityTracking(Entity) リンクを OrganizationServiceContext からデタッチした後に呼び出します。
OnExecuting(OrganizationRequest) 要求を Common Data Service に送信する直前に呼び出します。
OnExecute(OrganizationRequest, OrganizationResponse) 例外が発生したかどうかに関係なく、要求を Common Data Service に送信した直後に呼び出します。
OnSavingChanges(SaveChangesOptions) SaveChanges を呼び出した後の操作の前に呼び出します。
OnSaveChanges(SaveChangesResultCollection) SaveChanges の呼び出しに関するすべての操作が完了したとき、またはエラーが発生したときに呼び出します。

データ操作

組織サービス コンテキストのオブジェクトを変更、作成、および削除でき、これらのオブジェクトに対して行った変更は Common Data Service によって追跡されます。 OrganizationServiceContext.SaveChanges() メソッドが呼び出されると、Common Data Service は Common Data Service 内のデータに対して同等の挿入、更新、または削除 ステートメントを実行するコマンドを生成して実行します。

事前バインド エンティティ クラスを操作する場合は、エンティティ名と属性スキーマ名を使用して、操作するエンティティまたは属性を指定します。 属性スキーマ名は、EntityMetadata.SchemaName および AttributeMetadata.SchemaName で定義されるか、ユーザーがコード生成ファイルに示されるクラス名およびプロパティ名を使用することができます。次のサンプルでは、新しい連絡先インスタンスの電子メール属性に値を割り当てる方法を示します。

Contact contact = new Contact();
contact.EMailAddress1 = “sonny@contoso.com”;  

エンティティ レコードの新規作成

エンティティ データ モデルを使用して Common Data Service にデータを挿入する場合は、エンティティの種類のインスタンスを作成し、組織サービス コンテキストにオブジェクトを追加する必要があります。 組織サービス コンテキストは、オブジェクトを Common Data Service に保存する前にオブジェクトを追跡する必要があります。

新規エンティティ レコードを作成する場合は、AddObject(Entity) を使用して、組織サービス コンテキストにオブジェクトを追加します。 メソッド。

次のサンプルでは、エンティティ データ モデルを使用して新しい連絡先レコードをインスタンス化および保存する方法を示します。 また、カスタム属性にアクセスする方法も示します。

OrganizationServiceContext orgContext =new OrganizationServiceContext(svc);  
Contact contact = new Contact()     
 {  
   FirstName = "Charles",  
   LastName = "Brown",  
   Address1_Line1 = "123 Main St.",  
   Address1_City = "Des Moines",  
   Address1_StateOrProvince = "IA",  
   Address1_PostalCode = "21254",  
   new_twittername = "Chuck",  
   Telephone1 = "123-234-5678"  
 };   
orgContext.AddObject(contact);
orgContext.SaveChanges();  

前述のコード例にはいくつかの注意点があります。 最初に新しい取引先担当者のインスタンスを作成した後、取引先担当者オブジェクトを OrganizationServiceContext.AddObject(Entity) メソッドに渡し、コンテキストがオブジェクトの追跡を開始することができるようにします。 もう一つの注意点は、新しいオブジェクトをサーバーに保存するために OrganizationServiceContext.SaveChanges() メソッド。

オブジェクトをコンテキストに追加後、OrganizationServiceContext.SaveChanges() メソッドが呼び出される前に、コンテキストは新しいオブジェクトの ID を生成します。 Common Data Service データに対する更新が失敗した場合は、SaveChangesResults を含む例外が SaveChanges() メソッドからスローされます。

エンティティ レコードの更新

Common Data Service は、組織サービス コンテキストに添付されているオブジェクトに対する変更を追跡します。 既存のエンティティ レコードを変更するには、最初にオブジェクトをコンテキストに追加する必要があります。 オブジェクトをコンテキストに追加するには、Common Data Service からエンティティ レコードを取得してから、Attach(Entity) メソッドを使用してオブジェクトをコンテキストに追加する必要があります。 オブジェクトがコンテキストによって追跡された後、エンティティの属性を設定することでレコードを更新できます。

次のサンプルでは、事前バインド クラスを使用して取引先企業属性を更新する方法を示します。

Account.EMailAddress1 = “Contoso-WebMaster@contoso.com”;  

次のサンプルでは、属性値を削除する方法を示します。

Account.EMailAddress1 = null;  

各エンティティには、OnPropertyChangingおよび OnPropertyChanged という名前の 2 つの部分メソッドがあります。 これらのメソッドは、プロパティ セッターで呼び出されます。 これらのメソッドは、部分クラスを使用してカスタム ビジネス ロジックを挿入することで拡張できます。

エンティティ レコードの削除

エンティティ レコードを削除するには、組織サービス コンテキストでオブジェクトを追跡する必要があります。 オブジェクトがコンテキストに配置された後、DeleteObject(Entity) メソッドを使用して、コンテキスト上の削除するオブジェクトをマークできます。 Common Data Service のエンティティ レコードは、OrganizationServiceContext.SaveChanges() メソッドが呼び出されるまで削除されないことに注意してください。

関連項目

Common Data Service で、OrganizationServiceContext を使用した LINQ クエリの例
組織サービスを使用して事前バインド プログラミングのクラスを生成する
IOrganizationService
OrganizationServiceContext