3
votes

"EntityConnection can only be constructed with a closed DbConnection" This is the problem I get when a try to construct an entityconnection providing an open connection. There is a transactionscope open and I don't want to open a new connection or the transaction would be promoted to a dtc transaction as my understanding is that if I use a single SqlConnection over the multiple entityConnections, I don't need DTC.

So, my code is approximately like this.

Thanks in advance...

    using (TransactionScope transactionScope = new TransactionScope())
{

    using (SqlConnection dwConn = GetDWConnection(user)) 
    {
        dwConn.Open();
        // I need to do some SQlConnection specific actions first

        //EntityConnection specific actions next
        Func1(dwConn);
        Func2(dwConn); //similar to Func1()
        Func3(dwConn); //Similar to Func1()

    }

}
    Func1(SqlConnection dwConn)
    {
        using (EntityConnection conn = GetSQLEntityConnection(sqlConnection))
        {
            ObjectContext objectContext = (ObjectContext)Activator.CreateInstance(objectContextType, new object[] { conn });
            //few actions
        }
    }
    private EntityConnection GetSQLEntityConnection(SqlConnection sqlConnection)
        {
        //few steps
            EntityConnection entityConnection = new EntityConnection(entityConnectionStringBuilder.ToString());

            EntityConnection sqlEntityConnection = new EntityConnection(entityConnection.GetMetadataWorkspace(),sqlConnection);
            return sqlEntityConnection;
        }
2
why don't you pass the same ObjectContext instance?Eranga

2 Answers

2
votes

Jakub is completely right. You can create neither DbContext nor EntityConnection with opened DbConnection passed to them.

According to Diego B Vega’s post this issue will not be fixed until EF 6 release (here you can vote for it)

The workaround is to open already initialized EntityConnection before any operations involving it.

Given ObjectContext you can open EntityConnection like this:

((EntityConnection)objectContext.Connection).Open();

In case of DbContext the EntityConnection is available from underlying ObjectContext. The code might be like this:

class MyDbContext : DbContext
{
    public MyDbContext (DbConnection connection) 
                  : base (connection, contextOwnsConnection: true)
    {
        ((IObjectContextAdapter)this).ObjectContext.Connection.Open();
    }

    // …
}

class Program
{
    public static void Main()
    {
        var connection = new SqlConnection(CONNECTION_STRING);
        using (var database = new MyDbContext(connection))
        {
            Assert.IsTrue(connection.State == ConnectionState.Open);
        }
        Assert.IsTrue(connection.State == ConnectionState.Closed);
    }
}
0
votes

As you've already found out, you cannot create a new EntityConnection from an opened connection.

Instead of passing SqlConnection around and creating EntityConnection over and over again you should refactor your code and pass ObjectContext instead. ObjectContext is the root object in EF and you should favour it over SqlConnection.