ObjectContextManager connection sharing support for Entity Framework

ObjectContextManager connection sharing support for Entity Framework

Old forum URL: forums.lhotka.net/forums/t/11530.aspx


cornel_md posted on Wednesday, August 15, 2012

We are using one database and need to have separated edmx files, with different Model and ObjectContext class names. This results in having multiple connections string, which are different only in metadata part.

When I try create multiple contexts in the same TransactionScope, the System.Transactions infrastructure automatically escalates the transaction to be managed by the Microsoft Distributed Transaction Coordinator (MSDTC), which is disabled and an exception is thrown.

The generated entity classes have constructors that accept a EntityConnection, I don't know how to configure the ObjectContextManager to use that.

Is it possible to have a separate connectionString in config file and use that to initialize a SqlConnection and then use the connection to initialize all EF connections?

Thanks.

JonnyBee replied on Wednesday, August 15, 2012

You cannot use ObjectContextManager in this condition.

The whole point of ObjectContextManager is that it owns the Database connection and when there is no more references to the ObjectContextManager the connection is closed and disposed. THIS MEANS THAT 2 DIFFERENT MANAGERS CANNOT SHARE THE CONNECTION!!

So - essentially - you will have to create your own handling.

You might be able to use ConnectionManager<T> to handle the connection.

An EnitityConnection is a subclass of DbConnection and have several constructors - including one that accepts a "ConnectionString".

StefanCop replied on Thursday, August 16, 2012

Did you try to append an  "enlist=false"  to the connection strings?

sergeyb replied on Thursday, August 16, 2012

I do not believe this will work at all.  You cannot pass open connection to the context.  I belive that your only option is distributed transactions.

 

JonnyBee replied on Thursday, August 16, 2012

It is at best - a bit touchy and I didn't test for transactions - but I got it working for loading data:

Used Northwind database in SqlExpress and EF5.
EF CodeGenStrategy set to "Default" (to generate ObjectContext)
Added new class library and new model for Customer table only.
Added new class library and new model for Products table only.

        [STAThread]
        public static void Main()
        {
            var conn = new SqlConnection(@"data source=.\sqlexpress;initial catalog=Northwind;
                integrated security=True;MultipleActiveResultSets=True;App=EntityFramework");
            // create manual workspaces
            var workspace1 = new MetadataWorkspace(new string[] {"res://*/"},
                                                   new Assembly[] {typeof(NorthwindEntities1).Assembly});
            
            var workspace2 = new MetadataWorkspace(new string[] {"res://*/"},
                                                   new Assembly[] { typeof(NorthwindEntities2).Assembly});

            // conn must be closed when creating EntityConnections
            var econn1 = new EntityConnection(workspace1, conn);
            var econn2 = new EntityConnection(workspace2, conn);

            // Can open connection now and share the connection
            conn.Open();

            if (econn1.StoreConnection == econn2.StoreConnection)
                Console.WriteLine("Same connection");

            // Setup 2 models that share the Open DbConnection
            var nw1 = new NorthwindEntities1(econn1);
            var nw2 = new NorthwindEntities2(econn2);

            // fetch data from both models
            var customer = nw1.Customers.First();
            var product = nw2.Products.OrderBy(p=> p.ProductID).Skip(2).First();
            Console.WriteLine("{0}: {1}", customer.CustomerID, customer.CompanyName);
            Console.WriteLine("{0}: {1}", product.ProductID, product.ProductName);
            nw1.Dispose();
            nw2.Dispose();
            conn.Close();

            Console.ReadLine();
        }

output:

Same connection
ALFKI: Alfreds Futterkiste
3: Aniseed Syrup

The sequence of execution is very important here and as I said - I did not try transactions or updates to the database.

Copyright (c) Marimer LLC