2016-12-03 33 views
1

我正在使用Asp.Net MVC和实体框架。我有一个类为每个请求的管理事务如下: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(); 
    } 
} 

我想使用多个上下文作为解释here

我怎样才能改变TransactionPerRequset类?

回答

1

我已经这样做了,

关键的东西是把数据库连接生命周期的控制从EF走,走连接初始化,打开,关闭和处置照顾自己。

要做到这一点,你会用下列基地的DbContext构造:DbContext(DbConnection connection, Boolean contextOwnsConnection)

使用现有的连接到 连接到数据库构造一个新的上下文实例。如果contextOwnsConnection为假,则在处置 上下文时不会处理连接。

你应该在你的所有应用程序环境与暴露的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

我的意思是处理数据库连接的基础知识,你不想让它们保持开放或不处理。 –

相关问题