接続とトランザクションの管理 (Entity Framework)

既定では、Entity Framework によってデータベースへの接続が自動的に管理されます。 ただし、Entity Framework アプリケーションで接続とトランザクションの両方を手動で管理できます。

接続と Entity Framework

Entity Framework は、クエリの実行時や SaveChanges の呼び出し時などの必要な場合にのみ接続を開いて、処理が完了すると接続を閉じます。

以下のいずれかのメソッドを呼び出すと接続が開きます。

Bb896325.note(ja-jp,VS.100).gif注 :
クエリ メソッドが呼び出されると、接続が開きます。接続は、ObjectResult が完全に消費されるか破棄されるまで開いたままになります。

接続の手動管理

Entity Framework は、Connection プロパティを介して EntityConnection を公開します。 このため、接続とトランザクションを管理することや、独自の EntityConnection を提供することが可能です。 これは、パフォーマンスの向上またはトランザクションの明示的な制御を行うために、実行時間が短いオブジェクト コンテキスト内の接続を開いたままにする場合に便利です。 Entity Framework で使用された同一のプロバイダー接続は、アプリケーションの他の部分と共有できます。 次の例は、接続を明示的に開く方法を示します。

' Explicitly open the connection. 
context.Connection.Open()
// Explicitly open the connection.    
context.Connection.Open();

詳細については、「オブジェクト コンテキストから接続を手動で開く方法 (Entity Framework)」を参照してください。

実行時間の長いオブジェクト コンテキスト内で接続を手動で開いた場合は、コンテキストが不要になったときに Dispose メソッドを呼び出して接続を確実に閉じる必要があります。 また、EntityConnection に対して Close メソッドを呼び出して接続を明示的に閉じることもできます。 詳細については、「実行時間の長いオブジェクト コンテキストの接続を管理する方法 (Entity Framework)」を参照してください。

また、EntityConnection を作成して、その接続をオブジェクト コンテキストに提供することもできます。 その場合、手動で接続を開くか、必要なときにオブジェクト コンテキストで接続を開くことができます。 オブジェクト コンテキストに EntityConnection を提供した場合、コンテキストと EntityConnection が不要になった場合、これらを両方とも破棄する必要があります。 次の例では、接続を作成してオブジェクト コンテキストに渡します。

' Create an EntityConnection. 
Dim conn As New EntityConnection("name=AdventureWorksEntities")

' Create a long-running context with the connection. 
Dim context As New AdventureWorksEntities(conn)
// Create an EntityConnection.
EntityConnection conn =
    new EntityConnection("name=AdventureWorksEntities");

// Create a long-running context with the connection.
AdventureWorksEntities context =
    new AdventureWorksEntities(conn);

詳細については、「オブジェクト コンテキストで EntityConnection を使用する方法 (Entity Framework)」を参照してください。

接続の管理に関する注意点

接続を管理する際は、次の点に注意してください。

  • 操作の前に接続が既に開いていない場合、オブジェクト コンテキストによって接続が開かれます。 オブジェクト コンテキストによって操作中に接続が開かれた場合、接続は操作が完了したときに閉じられます。

  • 手動で接続を開いた場合、オブジェクト コンテキストによって接続が閉じられることはありません。 Close または Dispose を呼び出すと接続が閉じます。

  • オブジェクト コンテキストによって接続が作成された場合、接続は、コンテキストが破棄されたときに破棄されます。

  • 実行時間が長いオブジェクト コンテキストの場合、コンテキストが不要になったらコンテキストを破棄する必要があります。

開いている EntityConnection をオブジェクト コンテキストに提供した場合は、確実に破棄する必要があります。

トランザクションと Entity Framework

Entity Framework は自動トランザクション参加をサポートしています。 つまり、クエリの実行やデータ ソース内のデータに対する変更の保存など、オブジェクト コンテキスト内で実行されるアクティビティは、System.Transactions トランザクション内で操作を行うことによってデータ ソースで分離できます。 トランザクションを Entity Framework で使用すると、以下の操作ができます。

  • オブジェクトの変更が正常に完了しないと失敗するクエリなど、整合性の高さが求められる複数の操作をデータ ソースに対して行う。

  • 電子メール通知の送信やメッセージ キューへの書き込みなど、オブジェクト コンテキスト内の変更を他の分散処理に合わせてコーディネートする。

追加のリソース マネージャーを参加させることが必要となるトランザクションを、分散トランザクションと呼びます。 分散トランザクションでは、トランザクションの完了に必要なリソースを管理するために、分散トランザクション コーディネーター (DTC) を使用します。 トランザクションを DTC にエスカレートさせるプロセスには、作成と実行に比較的多くのリソースが必要になる場合があります。 SQL Server 2005 などの一部のリソース マネージャーでは、Promotable Single Phase Enlistment (PSPE) トランザクション プロトコルがサポートされています。 そのため、リソース マネージャーがホストするトランザクションは、分散トランザクション コーディネーター (DTC) によって管理されるように、後で必要に応じてエスカレートさせることができます。

System.Transactions の詳細については、「Transaction Processing」を参照してください。 System.Transactions を SQL Server で使用する方法の詳細については、「System.Transactions Integration with SQL Server (ADO.NET)」を参照してください。

トランザクションの管理に関する注意点

トランザクションを Entity Framework で使用する場合は、以下の点を考慮する必要があります。

  • データ ソースに対する操作のみがトランザクション処理されます。 オブジェクト コンテキストでのオブジェクトに対する変更は、トランザクション処理されません。 コンテキスト内のオブジェクトに対して加えた変更は、トランザクション スコープ外で表示されます。

  • SaveChanges を呼び出したときに現在のトランザクションが存在した場合、Entity Framework はデータ ソースの操作にこのトランザクションを使用します。 それ以外の場合は、操作用の新しいトランザクションが作成されます。 トランザクションを定義するには、EntityTransactionTransaction または TransactionScope を使用します。

    Bb896325.note(ja-jp,VS.100).gif注 :
    既存のトランザクションに参加するには、Entity Framework が接続をいったん閉じてから再度開く場合があります。

  • Entity Framework が SaveChanges 操作のために新しいトランザクションを作成した場合、オブジェクト コンテキスト内のオブジェクトの変更は、そのトランザクションが完了するまで受け入れられません。 これにより、オブジェクト コンテキストとデータ ソースの状態が一致するようになります。

  • 1 つのトランザクション内で接続が閉じて再度開かれると、トランザクションが DTC に昇格する場合があります。 Entity Framework は接続を自動的に開いて閉じるため、トランザクションの昇格を避けるためには、手動で接続を開いて閉じることを検討してください。 詳細については、「オブジェクト コンテキストから接続を手動で開く方法 (Entity Framework)」を参照してください。

  • トランザクションで操作を再試行する予定がある場合は、トランザクションが完了する前にコンテキスト内のオブジェクトのステータスがリセットされないようにする必要があります。 これを行うには、acceptChangesDuringSave パラメーターに値 false を指定して SaveChanges を呼び出してから、トランザクションの他の操作が正常に完了した後で AcceptAllChanges を呼び出します。 詳細については、「方法: Entity Framework のトランザクションを管理する」を参照してください。

コーディネート型トランザクションを使用した再試行操作では、AcceptAllChanges を最初に呼び出さずに、2 回目に SaveChanges を呼び出すことができます。 この場合、Entity Framework は同じ変更をデータ ソースに再適用しようとします。

このセクションの内容

オブジェクト コンテキストから接続を手動で開く方法 (Entity Framework)

実行時間の長いオブジェクト コンテキストの接続を管理する方法 (Entity Framework)

オブジェクト コンテキストで EntityConnection を使用する方法 (Entity Framework)

方法: Entity Framework のトランザクションを管理する