I have one MS Sql Server containing two databases. In a C# console application I have created two different entity data models (edmx) (EF6); one for DatabaseA and one for DatabaseB; applying the repository and unit of work patterns to both. Separately, they work well. No problems. What I am not able to figure out is how to bring both under a single 'transaction'.
Before EF, I would create SqlConnection and SqlTransaction, modify the relevant tables in either database within that transaction, then commit or rollback, as appropriate. But that doesn't seem to have an analog in EF.
UnitOfWorkForDatabaseA.Commit();
UnitOfWorkForDatabaseB.Commit(); //If this fails, both should rollback
But that doesn't seem possible with two separate units of work each with its own ObjectContext.
Do I need to surround them both in a TransactionScope? Or maybe design a SuperUnitOfWork?
Either use a TransactionScope and a Distributed Transaction (warning requires MSDTC), or use a single SqlConnection for both DbContext instances. You will have to manually switch the database context from the first database to the second by calling
To make this work the easiest way is to use TransactionScope (it will not be promoted to a DTC transaction since you're using a single SqlConnection).
eg
outputs
The reason you have to use TransactionScope here is that SaveChanges will otherwise use SqlTransaction internally. Fun fact: SqlTransaction is pretty badly broken. It requires manual SqlCommand enlistment, and it doesn't support nested transactions (which it calls "parallel transactions"). Any way it dates from .NET 1.0, and can't really be changed. It was made to work properly with System.Transactions when it appeared in .NET 2.0, though.