Ho una classe di servizio di comando, che utilizza l'unità di modello di lavoro, con vari metodi per aggiornare un database (SQL Azure, in questo caso) tramite il framework di entità.
Il servizio di comando viene istanziato con un riferimento a un'istanza di un dbcontext, la cui durata è gestita dal mio framework DI di scelta.
Alcuni dei metodi della classe del servizio di comando avviano più aggiornamenti al database all'interno di una transazione, ad esempio:
public void UpdateStuff(someEntity)
{
using(var tx = _db.Database.BeginTransaction())
{
//Some updates to db
_db.SaveChanges();
//Some other updates to db
_db.SaveChanges();
tx.Commit();
}
}
Ora, alcuni di questi metodi chiamano altri metodi della classe di comando all'interno delle loro transazioni, ad esempio:
public void UpdateWithSomeCascadingStuff(someOtherEntity)
{
using(var tx = _db.Database.BeginTransaction())
{
//Some updates to db
_db.SaveChanges();
//Some other cascading logic and updates to db
var relatedEntityToUpdate = _query.GetSomeEntityToUpdate(someOtherEntity);
UpdateStuff(relatedEntityToUpdate);
_db.SaveChanges();
tx.Commit();
}
}
Chiaramente, facendo questo, sto annidando le transazioni EF per la stessa istanza di DbContext.
Questo è supportato e causerà problemi? Esistono approcci alternativi che posso adottare?
AGGIORNAMENTO: sto usando prima il codice EF6
I DBContex di EntityFramework implementano entrambi i pattern UnitOfWork e Repository in sé.
Il contesto in EF6 avvolge automaticamente tutti i commit in una transazione in sé (se non è già parte di uno).
Quindi no, non dovresti condividere un contesto tra più unità di lavoro. Dovrebbero ognuno avere il proprio.
AGGIORNARE
Se provi ad avviare transazioni duplicate sullo stesso DbContext ottieni:
An unhandled exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll
Additional information: The connection is already in a transaction and cannot participate in another transaction. EntityClient does not support parallel transactions.
Quindi no, non puoi fare quello che stai chiedendo.