2016-12-03 8 views
1

私はAsp.Net MVCとEntity Frameworkを使用しています。私は次のように要求ごとのトランザクションを管理するためのクラスを持っている:EntityFrameworkの複数のdbcontextでのリクエストごとのトランザクション

public class TransactionPerRequest : 
    IRunOnEachRequest, IRunOnError, IRunAfterEachRequest 
{ 
    private readonly ContextDB _Context; 
    private readonly HttpContextBase _HttpContext; 

    public TransactionPerRequest(ContextDB context, 
     HttpContextBase httpContext) 
    { 
     _Context = context; 
     _HttpContext = httpContext; 
    } 

    void IRunOnEachRequest.Execute() 
    { 
     _HttpContext.Items["_Transaction"] = 
      _Context.Database.BeginTransaction(IsolationLevel.ReadCommitted); 
    } 

    void IRunOnError.Execute() 
    { 
     _HttpContext.Items["_Error"] = true; 
    } 

    void IRunAfterEachRequest.Execute() 
    { 
     var transaction = (DbContextTransaction)_HttpContext.Items["_Transaction"]; 

     if (_HttpContext.Items["_Error"] != null) 
      transaction.Rollback(); 
     else 
      transaction.Commit(); 
    } 
} 

は私がTransactionPerRequsetクラスを変更するにはどうすればよいhere

が説明したように、複数のコンテキストを使用するようにしたいですか?私はこれを行っている

答えて

1

重要な事は離れEFからデータベース接続のライフサイクルの制御を取ると、接続の初期化、オープン、クローズおよび廃棄自分自身の世話をすることです。

これを行うには、基本DbContextコンストラクタ以下を使用します:DbContext(DbConnection connection, Boolean contextOwnsConnection)

は には、データベースへの接続既存の接続を使用して、新しいコンテキストインスタンスを構築します。 contextOwnsConnectionがfalseの場合、 コンテキストが破棄されたときに接続が破棄されません。

あなたはすべてのアプリケーションのコンテキストでたDbConnectionを持つコンストラクタを公開し、あなたはDbContext外を作成同じ接続を注入しなければなりません。このようにして、EFはそれらを作成して開くことはできません。

最後に、接続マネージャークラスでは、DbConnection.BeginTransaction()を使用してDbTransactionオブジェクトを取得し、必要に応じて処理することができます。

以下は、アイデアを得るために必要なクラス変更の草案です。

public partial class ContextDB : DbContext 
{ 
    // New constructor 
    public ContextDB(DbConnection connection) 
     : base(connection, false) 
    { 
    } 
} 

public class TransactionPerRequest : 
    IRunOnEachRequest, IRunOnError, IRunAfterEachRequest 
{ 
    private readonly ContextDB _Context; 
    private readonly HttpContextBase _HttpContext; 
    private readonly DbConnection _cnn; 

    public TransactionPerRequest(HttpContextBase httpContext) 
    { 
     // Your code creates the connection 
     _cnn = new SqlConnection("Data Source=.;Initial Catalog=DB;Integrated Security=SSPI;"); 
     // Pass connection your context 
     _Context = new ContextDB(_cnn); 
     _HttpContext = httpContext; 
    } 

    void IRunOnEachRequest.Execute() 
    { 
     // Open connection 
     _cnn.Open(); 
     _HttpContext.Items["_Transaction"] = 
      _cnn.BeginTransaction(IsolationLevel.ReadCommitted); 
    } 

    void IRunOnError.Execute() 
    { 
     _HttpContext.Items["_Error"] = true; 
    } 

    void IRunAfterEachRequest.Execute() 
    { 
     var transaction = (DbContextTransaction)_HttpContext.Items["_Transaction"]; 

     if (_HttpContext.Items["_Error"] != null) 
      transaction.Rollback(); 
     else 
      transaction.Commit(); 

     _cnn.Close(); 
     _cnn.Dispose(); 
    } 
} 
+0

接続の初期化、開閉、処理および廃棄について説明できますか?ありがとう。 –

+0

私はデータベース接続を扱う基本を意味しました。あなたはそれらを開いたままにしておきたい、または破棄したくはありません。 –

関連する問題