N 層アプリケーションのビルド (Entity Framework)

Entity Framework では、Web サービスや Windows Communication Foundation (WCF) で使用される形式など、エンティティ オブジェクトのリモートおよびメッセージ ベースの交換を可能にする形式に、エンティティ オブジェクトをシリアル化できます。 オブジェクトをシリアル化するには、バイナリ ストリームまたはメッセージ ベースのプロトコルを使用したトランスポートのバイナリ シリアル化、XML シリアル化、および WCF コントラクト シリアル化を使用します。 詳細については、「オブジェクトのシリアル化 (Entity Framework)」を参照してください。 また、オブジェクトをメッセージまたはストリームから受信して、逆シリアル化し、オブジェクト コンテキストにアタッチすることもできます。 詳細については、「オブジェクトのアタッチとデタッチ (Entity Framework)」を参照してください。

また、ADO.NET Data Services により、アプリケーションで使用できる XML 形式のエンティティ データに動的にアクセスすることもできます。 このエンティティ データには、GET、PUT、POST などの標準の Representational State Transfer (REST) HTTP アクションを使用してアクセスします。 詳細については、「ADO.NET Data Services」を参照してください。

Entity Framework を使用する Web サービスまたは WCF サービスの場合は、以下の点を検討してください。

  • 関連オブジェクトは、バイナリ シリアル化およびデータ コントラクト シリアル化を使用して、プライマリ オブジェクトと共にシリアル化されます。 XML シリアル化では、関連オブジェクトはシリアル化されません。 エンティティをシリアル化する際には、遅延読み込みを無効にします。 遅延読み込みでは、アクセスされる各リレーションシップ ナビゲーション プロパティに対するクエリが実行されます。バイナリと WCF の両方のデータ コントラクト シリアライザーがすべてのリレーションシップ ナビゲーション プロパティにアクセスします。 これによって、シリアル化中に多くの予期しないクエリが実行される可能性があります。 詳細については、「オブジェクトのシリアル化 (Entity Framework)」を参照してください。

  • ステートレスなサービスを使用することをお勧めします。 オブジェクト コンテキストが要求時または応答時にのみ保持されるように、サービスを設計する必要があります。 メッセージ交換のパターンには、オブジェクトを保持したり、データ ソースを再クエリして元のオブジェクトを取得したりする必要なく変更を適用するのに十分な情報が含まれる必要があります。 たとえば、クライアントによるオブジェクトの更新を可能にするサービスでは、更新されたオブジェクトが元のオブジェクトと共に返される必要があります。 これにより、データベースから元のオブジェクトを取得したり、メモリに元のオブジェクトを保存したりする必要なく、Web サービスによって元のオブジェクトに変更を適用できます。 詳細については、「デタッチされたオブジェクト対して行われた変更を適用する方法 (Entity Framework)」を参照してください。

  • オブジェクトは常に、Detached 状態で逆シリアル化されます。 ObjectContext へのオブジェクトのアタッチまたは追加が必要になることがあります。または、プロパティの変更を元のオブジェクトに適用することもできます。 詳細については、「オブジェクトのアタッチとデタッチ (Entity Framework)」を参照してください。

  • オブジェクトとリレーションシップがコンテキストに追加されたら、ChangeObjectState (AddedModified など) を使用して新しい状態を設定できます。

  • 同時実行と検証を手動で管理する必要があります。

詳細については、N 層の開発に関する次の記事を参照してください。

アンチ パターン

n 層アプリケーションのパターン

自己追跡エンティティ

Entity Framework アプリケーションでは、オブジェクトの変更はオブジェクト コンテキストによって追跡されます。 ただし、オブジェクト コンテキストを利用できない別の階層でオブジェクトの操作が必要な場合、変更の追跡方法を指定し、これらの変更内容をオブジェクト コンテキストにレポートする必要があります。 .NET Framework バージョン 4 以降では、自己追跡エンティティを使用してすべての階層で変更を追跡できるようになりました。 自己追跡エンティティは、スカラー プロパティ、複合プロパティ、およびナビゲーション プロパティの変更を報告できるエンティティ型を生成する、テキスト テンプレート変換ツールキット (T4) テンプレートから構築されます。 詳細については、「自己追跡エンティティの使用」を参照してください。

自己追跡エンティティを使用しないでオブジェクト コンテキストにオブジェクトがアタッチされていない層の変更内容を追跡するには、次のセクションのメソッドを使用してコンテキストを更新し、関連する変更をデータベースに保存します。

N 層アプリケーションの開発に関連する API の操作

次のメソッドを使用すると、オブジェクトのグラフ全体を追加し、そのグラフを確認し、オブジェクトのプロパティに適切な値を適用し、エンティティ オブジェクトおよびリレーションシップを適切な状態に設定できます。

エンティティを追加しアタッチするには、次のメソッドを使用します。

メンバー 説明

System.Data.Objects.ObjectSet.AddObject(

または

System.Data.Objects.ObjectContext.AddObject(System.String,System.Object)

オブジェクトとその関連オブジェクトを ObjectContext に追加し、エンティティ オブジェクトを Added 状態に設定します。 この状態では、一意のキー値を持つためにエンティティ オブジェクトは必要ありません。 一時的なキー値がキーのプロパティに割り当てられ、オブジェクトの保存後にデータ ソースが生成した値で更新されます。 オブジェクトを追加後、エンティティ オブジェクトの状態を適切に変更します。

System.Data.Objects.ObjectSet.Attach(

または

System.Data.Objects.ObjectContext.Attach(System.Data.Objects.DataClasses.IEntityWithKey)

および

AttachTo

オブジェクトを ObjectContext に追加し、オブジェクトを Unchanged 状態に設定します。 Unchanged 状態では、Entity Framework はエンティティ キーの値を最終版として処理します。 特定の型の複数のエンティティに同じキーの値がある場合は、Entity Framework は例外をスローします。 例外を回避するには、AddObject メソッドを使用してデタッチされたオブジェクトをアタッチし、適切な状態に変更します。

スカラー値を変更するには、次のメソッドを使用します。

メンバー 説明

System.Data.Objects.ObjectSet.ApplyCurrentValues(

または

System.Data.Objects.ObjectContext.ApplyCurrentValues.String,

指定されたオブジェクトのスカラー値を、同じキーを持つ ObjectContext のオブジェクトにコピーします。 元の値と異なる値は変更済みとしてマークされます。

現在の値を使用しているグラフに元の値を適用するには、ApplyOriginalValues メソッドを呼び出します。

また、ObjectStateEntryApplyCurrentValues メソッドを使用できます。

System.Data.Objects.ObjectSet.ApplyOriginalValues(

または

System.Data.Objects.ObjectContext.ApplyOriginalValues.String,

指定されたオブジェクトのスカラー値を、同じキーを持つ ObjectContext のオブジェクトの一連の元の値にコピーします。 現在の値と異なる値は変更済みとしてマークされます。

また、ObjectStateEntryApplyOriginalValues メソッドを使用できます。

SetModifiedProperty

個々のプロパティを Modified 状態に設定します。 エンティティ全体を変更済みに設定するのではなく、変更されたプロパティがわかっている場合に、このプロパティを使用します。

GetUpdatableOriginalValues

この ObjectStateEntry に関連付けられているオブジェクトの元の値の更新可能なバージョンを表す OriginalValueRecord インスタンスを取得します。 返された OriginalValueRecord インスタンスを使用して、オブジェクトの元のプロパティを個別に読み取ったり更新したりします。

CurrentValues

この ObjectStateEntry に関連付けられているオブジェクトの現在の値を表す CurrentValueRecord インスタンスを取得します。 返された CurrentValueRecord インスタンスを使用して、オブジェクトの現在のプロパティを個別に読み取ったり更新したりします。

エンティティおよびリレーションシップの状態を変更するには、次のメソッドを使用します。

メンバー 説明

ChangeObjectState

エンティティまたはリレーションシップを新しい状態 (AddedModified など) に変更します。 この変更を行うと、エンティティが参加しているリレーションシップに影響を与える場合があります。 たとえば、エントリを Added 状態に移動すると、変更されていないリレーションシップも Added 状態に移動します。 同様に、エンティティに Modified のマークを付けると、すべてのスカラー値にも Modified のマークが付きます。

また、ObjectStateEntryChangeState メソッドを使用できます。

ChangeRelationshipState

2 つのエンティティ間の既存のリレーションシップを、指定した状態に変更します。 エンティティ間にリレーションシップがない場合は、指定された状態の新しいリレーションシップがこのメソッドによって作成されます。 このメソッドは、外部キーの関連付けに基づくリレーションシップではサポートされていません。 詳細については、「リレーションシップの定義と管理 (Entity Framework)」を参照してください。

また、ObjectStateEntryChangeState メソッドを使用できます。

ChangeState

このメソッドは、ObjectStateEntry がオブジェクトかリレーションシップであるかによって、ChangeObjectStateChangeRelationshipState と同様に動作します。

SetModifiedProperty

個々のプロパティを Modified 状態に設定します。 エンティティ全体を変更済みに設定するのではなく、変更されたプロパティがわかっている場合に、このメソッドを使用します。

変更をデータ ソースに保存するには、次のメソッドを使用します。

メンバー 説明

SaveChanges

すべての変更をデータ ソースに保存します。

オブジェクトの具体化時に、情報を取得または設定する場合、またはイベントにサブスクライブする場合は、ObjectMaterialized イベントを使用します。

メンバー 説明

ObjectMaterialized

クエリまたは読み込み操作の一部として、データ ソース内のデータから新しいエンティティ オブジェクトが作成されたときに発生します。 イベントは、コレクションの読み込み前ではなく、参照オブジェクトの読み込み後に生成されます。 同じキー値を持つオブジェクトがコンテキストに存在する場合、Entity Framework はオブジェクトを再作成せず、このイベントは発生しません。

参照

概念

オブジェクトの使用 (Entity Framework)