Usiamo ASP.Net MVC + Autofac + EF6. DbContext è racchiuso da UnitOfWork. Lo creiamo per ogni richiesta http tramite Autofac. Apriamo anche la transazione per l'intera richiesta http nel costruttore UnitOfWork.
Il problema è che non tutte le richieste HTTP devono essere incluse nella transazione. Alcuni di loro non hanno nemmeno richieste al DB.
Vorremmo ritardare l'apertura della transazione fino alla prima effettiva richiesta a DB. Qualche idea su come si può fare?
Possiamo sovrascrivere SaveChages e aprire la transazione prima del salvataggio, ma le query selezionate non verranno eseguite nella transazione in questo modo.
Un altro problema qui: utilizziamo i filtri globali da EF Plus per entità rimovibili morbide. Funziona bene, ma l'inizializzazione dei filtri per il contesto è piuttosto lenta. Vorremmo ritardarlo fino alla prima effettiva richiesta anche a DB.
Il problema è che il tuo UnitOfWork
viene iniettato nel controller nonostante un'azione venga chiamata e quindi il suo costruttore viene sempre chiamato anche se non è necessario utilizzarlo. Una soluzione potrebbe essere l'utilizzo dell'iniezione pigra di Autofac. In questo caso il constuctor di UnitOfWork
viene chiamato solo quando è necessaria la sua istanza
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);
}
}