自己追跡エンティティの使用

Entity Framework アプリケーションでは、オブジェクト グラフ内のエンティティの変更はオブジェクト コンテキストによって追跡されます。ただし、N 層シナリオでは、エンティティを変更する層でオブジェクト コンテキストを利用できない場合があります。.NET Framework Version 4 以降では、自己追跡エンティティを使用してすべての層で変更を追跡できるようになりました。

Ff407090.note(ja-jp,VS.100).gif注 :
自己追跡エンティティは、オブジェクト グラフに対する変更が行われる層でオブジェクト コンテキストを利用できない場合にのみ使用します。オブジェクト コンテキストを利用できる場合は、EntityObject 派生型、POCO ("plain-old" CLR object) 型、または POCO プロキシ型を使用します。詳細については、「オブジェクトの使用 (Entity Framework)」を参照してください。

Microsoft Visual Studio 2010 以降では、自己追跡エンティティは、ADO.NET Self-Tracking Entity ジェネレーター テンプレートによって生成されます。このテンプレート項目は、<モデル名>.tt および <モデル名>.Context.tt という 2 つの .tt (テキスト テンプレート) ファイルを生成します。<モデル名>.tt ファイルは、エンティティ型と、自己追跡エンティティが使用する変更追跡ロジックおよび自己追跡エンティティで状態設定が可能な拡張メソッドを含むヘルパー クラスを生成します。<モデル名>.Context.tt ファイルは、型指定された ObjectContext と、ObjectContext クラスおよび ObjectSet クラスの ApplyChanges メソッドを含む拡張クラスを生成します。これらのメソッドは、自己追跡エンティティのグラフに含まれている変更追跡情報を検証して、データベースに変更内容を保存するために実行しなければならない一連の操作を推論します。詳細については、「ADO.NET Self-Tracking Entity Generator Template」を参照してください。

Ff407090.Important(ja-jp,VS.100).gif 注 :
サービスは、信頼されていないクライアントからの、または信頼されていないチャネルを経由した、データの取得または更新の要求を信頼しません。クライアントは認証されている必要があります。また、セキュリティで保護されたチャネルまたはメッセージ エンベロープを使用する必要があります。クライアントによるデータの取得または更新の要求は、特定のシナリオに対して予想される正当な変更に準拠することを確認するために検証する必要があります。

Ff407090.Important(ja-jp,VS.100).gif 注 :
機密情報 (社会保障番号など) をエンティティ キーとして使用しないでください。これにより、完全に信頼されていないクライアントに自己追跡エンティティのグラフ内の機密情報が誤ってシリアル化される可能性が低くなります。独立した関連付けでは、シリアル化される情報に関連するエンティティの元のキーは、クライアントにも送信される可能性があります。

自己追跡エンティティの拡張メソッド

自己追跡エンティティに適用できる拡張メソッドを次に示します。1 つのエンティティではなくエンティティのセットでこれらの操作を実行する場合は、「自己追跡エンティティのセットの使用」で詳細について参照してください。

StartTracking メソッド

StartTracking メソッドは、エンティティに適用された変更の記録を開始するようにエンティティの変更トラッカーに指示します。これには、スカラー プロパティ、コレクション、および他のエンティティへの参照に対する変更が含まれます。自己追跡エンティティは、Windows Communication Foundation (WCF) を通じてクライアントに逆シリアル化されると自動的に追跡を開始します。また、次のシナリオで新しく作成されたエンティティに対しても、追跡が有効になります。

  • 新しいエンティティと既に変更を追跡しているエンティティとの間にリレーションシップが作成される場合。

  • エンティティで MarkAs[State] メソッドまたは AcceptChanges メソッドが呼び出される場合。

StopTracking メソッド

StopTracking メソッドは、変更の記録を停止します。

MarkAs メソッド

すべての MarkAs メソッドは追跡を有効にします。これらの拡張メソッドにより、エンティティの状態を AddedModifiedDeleted、および Unchanged に明示的に変更することが容易になります。

MarkAs[State] メソッドは、このメソッドが適用されるエンティティを、状態を変更して返します。エンティティの状態を Unchanged に変更する例を次に示します。

department.Course = new Course { CourseID = courseID }.MarkAsUnchanged();

MarkAsAdded メソッドは、エンティティの状態を Added に変更します。新しい自己追跡エンティティは、変更の追跡が無効になっている Added 状態で作成されます。

MarkAsDeleted メソッドは、エンティティの状態を Deleted に変更します。また、このメソッドは、削除対象としてマークされているエンティティのナビゲーション プロパティをクリアします。ナビゲーション プロパティが参照オブジェクトを指している場合、このプロパティは null に設定されます。ナビゲーション プロパティがコレクションを表す場合は、Clear メソッドが呼び出されます。コレクションに含まれるオブジェクトで MarkAsDeleted が呼び出されると、そのオブジェクトがコレクションから削除されます。コレクション内の各オブジェクトを削除済みとしてマークするには、コレクションのコピーのオブジェクトをマークします。コレクションのコピーを取得するには、次の例に示すように、コレクションで ToArray() メソッドまたは ToList() メソッドを呼び出します。

List<Course> courses = department.Courses.ToList();

foreach (var c in courses)

{

// Mark each course in the department as Deleted.

c.MarkAsDeleted();

}

MarkAsModified メソッドは、エンティティの状態を Modified に変更します。また、変更の追跡が有効になっているエンティティのプロパティの値を変更すると、状態は Modified に設定されます。

MarkAsUnchanged メソッドは、エンティティの状態を Unchanged に変更します。また、AcceptChanges はエンティティの変更追跡情報をクリアし、その状態を Unchanged に変更します。

AcceptChanges

AcceptChanges メソッドは、エンティティの変更追跡情報をクリアし、その状態を Unchanged に変更します。リレーションシップの状態をリセットする場合は、そのリレーションシップに参加している 2 つのエンティティで AcceptChanges を呼び出します。

ObjectContext 拡張メソッド

ApplyChanges メソッドは、自己追跡エンティティのグラフに含まれている変更追跡情報を検証して、データベースに変更内容を反映するために実行する必要のある一連の操作を推論します。ObjectContext 用と ObjectSet 用の 2 つの ApplyChanges メソッドがあります。

Ff407090.note(ja-jp,VS.100).gif注 :
機密データを含む例外メッセージがクライアント層に反映されないように、サーバー層での ApplyChanges および SaveChanges の呼び出しを例外処理コードにラップする必要があります。

自己追跡エンティティの使用に関する考慮事項

自己追跡エンティティを使用する際は、次の点に注意してください。

  • エンティティ型を含むアセンブリへの参照がクライアント プロジェクトにあることを確認します。クライアント プロジェクトにサービス参照のみ追加する場合、クライアント プロジェクトは実際の自己追跡エンティティ型ではなく WCF プロキシ型を使用します。つまり、クライアントでエンティティの追跡を管理する自動通知機能を取得することはできません。エンティティ型を意図的に含めない場合は、クライアントで変更追跡情報を手動で設定して、変更内容がサービスに送り返されるようにする必要があります。

  • サービス操作の呼び出しはステートレスで行い、この呼び出しによってオブジェクト コンテキストの新しいインスタンスを作成する必要があります。また、using ブロックにオブジェクト コンテキストを作成することをお勧めします。

  • クライアントで変更されたグラフをサービスに送信した後、クライアントで同じグラフを引き続き使用する場合は、グラフを手動で反復処理し、各オブジェクトで AcceptChanges メソッドを呼び出して変更トラッカーをリセットする必要があります。データベースによって生成される値 (たとえば、ID や同時実行の値) を持つプロパティがグラフ内のオブジェクトに含まれている場合、Entity Framework では、SaveChanges メソッドが呼び出された後に、それらのプロパティの値をデータベースによって生成される値に置き換えます。サービス操作を実装して、保存されたオブジェクトまたはオブジェクト用に生成されたプロパティ値の一覧をクライアントに返すことができます。その後で、クライアントはオブジェクト インスタンスまたはオブジェクトのプロパティ値を、サービス操作から返されるオブジェクトまたはプロパティ値に置き換える必要があります。

  • 複数のサービス要求からグラフをマージすると、作成されるグラフでオブジェクトのキー値が重複する可能性があります。ApplyChanges メソッドを呼び出す場合、Entity Framework では重複キーを持つオブジェクトを削除せず、代わりに例外がスローされます。グラフでキー値が重複しないようにするには、ブログの記事「自己追跡エンティティ: ApplyChanges および重複するエンティティ」で説明されているいずれかのパターンに従ってください。

  • 外部キーのプロパティを設定してオブジェクト間のリレーションシップを変更すると、参照ナビゲーション プロパティは null に設定され、クライアントの適切なプリンシパル エンティティと同期されません。グラフがオブジェクト コンテキストにアタッチされた後 (たとえば、ApplyChanges メソッドの呼び出し後)、外部キーのプロパティとナビゲーション プロパティが同期されます。

    参照ナビゲーション プロパティが適切なプリンシパル オブジェクトと同期されない場合は、外部キーのリレーションシップで連鎖削除を指定していた場合に問題となる可能性があります。プリンシパルを削除すると、依存オブジェクトに削除が反映されません。連鎖削除を指定していた場合は、外部キーのプロパティを設定する代わりに、ナビゲーション プロパティを使用してリレーションシップを変更します。

  • 自己追跡エンティティは遅延読み込みを実行できません。

  • ADO.NET Self-Tracking Entity ジェネレーター テンプレートから生成されるコードでは、バイナリ シリアル化および ASP.NET 状態管理オブジェクトへのシリアル化はサポートされていません。ただし、バイナリ シリアル化のサポートを追加するようにテンプレートをカスタマイズできます。詳細については、「自己追跡エンティティでのバイナリ シリアル化および ViewState の使用」を参照してください。

参照

処理手順

チュートリアル: 自己追跡エンティティのシリアル化 (Entity Framework)

その他のリソース

自己追跡エンティティのセットの使用
Silverlight の自己追跡エンティティ
自己追跡エンティティでのバイナリ シリアル化および ViewState の使用