Ayende @ Rahien

Hi!
My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

+972 52-548-6969

, @ Q c

Posts: 5,953 | Comments: 44,408

filter by tags archive

Entity Framework: If you pass a connection to the context, you are responsible for disposing it


I recently got a bug report about an issue with EF Prof, apparently the application statistics would record the context being opened, but it wouldn’t show them being closed. The customer was rightfully worried about that, and wanted to know if this is a bug in his code or in EF Prof.

Not closing connections is a pretty bad idea, obviously, because you are going to hold a lot more server resources than you need.

But we couldn’t figure out what the problem was. On my end, I could see that EF Prof was recording the context close properly, but nearly the same code on the customer showed the problem. Note the word nearly. I asked for a repro of the issue, and once I had it, it took mere minutes to confirm that the problem exists.

Now was the time to find out why. The customer code was:

using(var context = new MyContext(new EntityConnection("name=MyConStr"))
{
   // do stuff
}

Now, what EF Prof tells you is a data context open & close are actually more accurately connection open & close. After some extensive study, I verified that it wasn’t my code to blame, there was a leaking connection here.

Checking a bit further, it became clear. We passed an existing connection to the context. When we dispose the context, the context asks: “Am I the owner of this connection?” And since the answer is no, it will not dispose it. It makes sense, you might want to use that connection for your own purposes, and it is pretty rude of the context to close a connection that it doesn’t own.

How can we resolve this? By giving the context the information to open the connection, but not the connection itself:

using(var context = new MyContext("name=MyConStr")
{
   // do stuff
}

This code will instruct the context to open its own connection, which it will know that it owns, so it can safely dispose it when it is disposed.

Look Ma, no leaks!


Comments

Damien Guard

This applies to LINQ to SQL too - if the connection is a string it will open and close, if it is an existing connection it will not.

[)amien

configurator

Indeed, classes that accept parameters should not dispose of their parameters; whoever opened the connection should be responsible for closing it.

StreamReader and StreamWriter fail miserably there. Try

using (MemoryStream s = new MemoryStream) {

using (StreamWriter writer = new StreamWriter(s))

writer.write(something);

s.Seek(0);

using (StreamReader reader = new StreamReader(s))

reader.ReadToEnd();

}

Mladen

Maybe i'm misunderstanding something here but how is new-ing an EntityConnection using an existing connection?

if you do:

new MyContext(new EntityConnection("name=MyConStr"))

shouldn't that create a new connection in that context?

maybe EF does this differently but i haven't worked with EF yet, so maybe i'm missing something here.

Ayende Rahien

Mladen,

How is EF to know that you didn't pass it from someplace totally different?

Mladen

ahhhhhh.... now i got it. If you pass any connection into it! DOH!

Comment preview

Comments have been closed on this topic.

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. The RavenDB Comic Strip (3):
    28 May 2015 - Part III – High availability & sleeping soundly
  2. Special Offer (2):
    27 May 2015 - 29% discount for all our products
  3. RavenDB Sharding (3):
    22 May 2015 - Adding a new shard to an existing cluster, splitting the shard
  4. Challenge (45):
    28 Apr 2015 - What is the meaning of this change?
  5. Interview question (2):
    30 Mar 2015 - fix the index
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats