Liwq
Liwq

Reputation: 11

Entity Framework 6 Multiple Datacontext Sharing a transaction

using(var Db = new Framework_DbContext())
{
    var DbContextTransaction = Db.Database.BeginTransaction(IsolationLevel.ReadUncommitted);
    using (var db = new DocumentLibDbContext())
    {
        //**How to use the above DbContextTransaction??**
        db.Database.UseTransaction(DbContextTransaction.UnderlyingTransaction);
    }
}

Upvotes: 1

Views: 1718

Answers (1)

You didn't specify whether your contexts connect to the same database or not.

If the databases are different, you need to avoid BeginTransaction and UseTransactionand instread wrap your code in a TransactionScope.

Assuming they both connect to the same database, you don't specify whether you are using an EDMX or Code First. I had the same problem using EDMX, spent the whole day with trial and error and finally came up with a solution.

var workspace = new MetadataWorkspace(new[] { "res://*/" }, new[] { Assembly.GetExecutingAssembly() });
using (var connection = new SqlConnection("data source=.;initial catalog=MultpleEdmxTest;integrated security=True;MultipleActiveResultSets=True"))
{
    using (var entityConnection1 = new EntityConnection(workspace, connection, false))
    {
        using (var entityConnection2 = new EntityConnection(workspace, connection, false))
        {
            connection.Open();
            using (var transaction = connection.BeginTransaction())
            {
                using (var schema1Entities = new Schema1Entities(entityConnection1))
                {
                    schema1Entities.Database.UseTransaction(transaction);
                    // code goes here
                    schema1Entities.SaveChanges();
                }

                using (var schema2Entities = new Schema2Entities(entityConnection2))
                {
                    schema2Entities.Database.UseTransaction(transaction);
                    // code goes here
                    schema2Entities.SaveChanges();
                }
                transaction.Commit();
            }
        }
    }
}

You define the extra constructors in partial classes like so:

partial class Schema1Entities
{
    public Schema1Entities(DbConnection connection) : base(connection, false) { }
}

where false indicates that you open and close the connection manually.

As a bonus you now only need one connection string in your config and it doesn't include all the useless EF junk that normally comes with it (metadata=res://*/blabla).

Upvotes: 1

Related Questions