asp.net-mvctransactionsentity-framework-6autofacentity-framework-plus

How to delay transaction open in EF6?


We use ASP.Net MVC + Autofac + EF6. DbContext is wrapped by UnitOfWork. We create it for each http request via Autofac. We also open transaction for whole http request in UnitOfWork constructor.

The problem is that not all http requests have to be wrapped in to the transaction. Some of them even don't have requests to DB.

We'd like to delay transaction open till the first actual request to DB. Any ideas how one can do it?

We can override SaveChages and open transaction before save, but select queries will not be executed in transaction this way.

One more problem here: we use global filters from EF Plus for soft removable entities. It works good, but filters initialization for context is rather slow. We'd like to delay it till the first actual request to DB too.


Solution

  • The problem is that your UnitOfWork is injected into controller despite an action being called and therefore its constructor is always called even if you don't need to use it. One solution could be using Autofac lazy injection. In this case UnitOfWork's constuctor is called only when its instance is needed

    public class SomeController : Controller {
        //..
        private readonly Lazy<IUnitOfWork> _unitOfWork;
    
        private IAnotherService UnitOfWork => _unitOfWork.Value;
    
        public SomeController(
            //..
            Lazy<IUnitOfWork> unitOfWork
            )
        {
            //..
            _unitOfWork = unitOfWork;
        }
    
        //..
        public ActionResult ActionNeedsTransaction()
        {
            //use UnitOfWork
    
            UnitOfWork.SaveChanges();
    
            return Json(value);
        }
    
    }