OrganizationServiceContext の使用

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

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

OrganizationServiceContext クラスの使用方法

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

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

// For early bound types to work correctly, they have to be enabled on the
// client connection. Here, _service is a reference to a ServiceClient or
// CrmServiceClient object. Those types implement IOrganizationService.
_service.EnableProxyTypes();
AdventureWorksCycleServiceContext context = new   
    AdventureWorksCycleServiceContext(_service);  

コンテキスト インスタンスを作成したら、テーブル行 (エンティティ レコード) の作成、変更、削除の追跡を開始できます。

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

変更を追跡する

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

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

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

Dataverse では、サービス コンテキストでテーブル行間の関連付けを作成および更新できます。 Power Platform CLI pac modelbuilder ビルド コマンド で生成され、事前バインド クラスに配置されるナビゲーション プロパティで、関連する行のプロパティや関連付けへのアクセスや変更を行うことができます。 関連する行をサーバーで更新できるようにするには、サービス コンテキストで関連する行を追跡する必要があります。

関連する行を操作する場合、およびサービス コンテキストに行を追加する場合は、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) 要求を Dataverse に送信する直前に呼び出します。
OnExecute(OrganizationRequest, OrganizationResponse) 例外が発生したかどうかに関係なく、要求を Dataverse に送信した直後に呼び出します。
OnSavingChanges(SaveChangesOptions) SaveChanges を呼び出した後の操作の前に呼び出します。
OnSaveChanges(SaveChangesResultCollection) SaveChanges の呼び出しに関するすべての操作が完了したとき、またはエラーが発生したときに呼び出します。

データ操作

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

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

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

新しいテーブル行を作成する

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

新規テーブル行を作成する場合は、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 を生成します。 Dataverse データに対する更新が失敗した場合は、SaveChangesResults を含む例外が SaveChanges() メソッドからスローされます。

テーブル行を更新する

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

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

Account.EMailAddress1 = "Contoso-WebMaster@contoso.com";  

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

Account.EMailAddress1 = null;  

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

行を削除する

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

関連項目

Dataverse で、OrganizationServiceContext を使用した LINQ クエリの例
.NET 用 SDK を使用して事前バインド プログラミングのクラスを生成する
IOrganizationService
OrganizationServiceContext

注意

ドキュメントの言語設定についてお聞かせください。 簡単な調査を行います。 (この調査は英語です)

この調査には約 7 分かかります。 個人データは収集されません (プライバシー ステートメント)。