Con Entity Framework la maggior parte del tempo SaveChanges()
è sufficiente. Questo crea una transazione o si arruola in qualsiasi transazione ambientale e fa tutto il lavoro necessario in quella transazione.
A volte però l' SaveChanges(false) + AcceptAllChanges()
abbinamento è utile.
Il posto più utile per questo è nelle situazioni in cui si desidera eseguire una transazione distribuita tra due diversi contesti.
Vale a dire qualcosa del genere (male):
using (TransactionScope scope = new TransactionScope())
{
//Do something with context1
//Do something with context2
//Save and discard changes
context1.SaveChanges();
//Save and discard changes
context2.SaveChanges();
//if we get here things are looking good.
scope.Complete();
}
Se context1.SaveChanges()
riesce ma context2.SaveChanges()
fallisce l'intera transazione distribuita viene interrotta. Ma sfortunatamente Entity Framework ha già scartato le modifiche context1
, quindi non è possibile riprodurre o registrare efficacemente l'errore.
Ma se modifichi il codice in questo modo:
using (TransactionScope scope = new TransactionScope())
{
//Do something with context1
//Do something with context2
//Save Changes but don't discard yet
context1.SaveChanges(false);
//Save Changes but don't discard yet
context2.SaveChanges(false);
//if we get here things are looking good.
scope.Complete();
context1.AcceptAllChanges();
context2.AcceptAllChanges();
}
Mentre la chiamata a SaveChanges(false)
invia i comandi necessari al database, il contesto stesso non viene modificato, quindi è possibile farlo di nuovo se necessario, oppure è possibile interrogare ObjectStateManager
se lo si desidera.
Ciò significa che se la transazione genera effettivamente un'eccezione che è possibile compensare, riprovando o registrando lo stato di ciascun contesto ObjectStateManager
da qualche parte.
Vedi il mio post sul blog per ulteriori informazioni.
SaveChanges(fase); ... AcceptAllChanges();
era uno schema in primo luogo. Notare come la risposta accettata alla domanda sopra, è scritta dall'autore di un blog e a quel blog viene fatto riferimento nell'altra domanda. Tutto viene insieme.