Entity Framework 6 Database First - How to share connection and transaction with ADO

912 views Asked by At

Is it possible to share one connection (and transaction as well) between operations made in EF6 DB First approach and some ADO operations?

As I read here: https://msdn.microsoft.com/en-us/data/dn456843.aspx#existing it is possible to share connection and transactions since EF v6, but I have to pass SqlConnection object as a parameter to the constructor of context class. But if I do that in DB First approach , I've got UnintentionalCodeFirstException.

As I read here: https://msdn.microsoft.com/en-us/data/jj592674 I have to use instance of EntityConnection as a parameter to the constructor of context class when DB First approach is used. But EntityConnection class constructor accept only CLOSED connections. And therefore I cannot share transaction, because connection has to be closed before passed to context class.

Am I right and it is impossible to share one connection in this scenario, or maybe there is some other way?

Is TransactionScope still the only way to wrap operations in EF 6 DB First and ADO in a transaction (with separate connections) ?

1

There are 1 answers

0
Giorgi Nakeuri On

I can not remember where I did get this from, but it helped me with running EF and SqlBulkCopy in same transaction. Here is how to grab transaction with reflection from Entity Framework:

EntityConnection ec = (EntityConnection)Context.Connection;
SqlConnection sc = (SqlConnection)ec.StoreConnection;
SqlTransaction sqlTransaction = null;

var parserProp = sc.GetType().GetProperty("Parser", BindingFlags.NonPublic | BindingFlags.Instance);

if (parserProp != null)
{
    var parser = parserProp.GetValue(sc, null);
    var sqltxProp = parser.GetType().GetProperty("CurrentTransaction", BindingFlags.NonPublic | BindingFlags.Instance);
    var currentTransaction = sqltxProp.GetValue(parser, null);
    sqlTransaction = currentTransaction as SqlTransaction;

    if (sqlTransaction == null)
    {
        var parentProp = currentTransaction.GetType().GetProperty("Parent", BindingFlags.NonPublic | BindingFlags.Instance);
        currentTransaction = parentProp.GetValue(currentTransaction, null);
        sqlTransaction = currentTransaction as SqlTransaction;
    }
}