67

The Entity Framework context object implements a Dispose() method which "Releases the resources used by the object context". What does it do really? Could it be a bad thing to always put it into a using {} statement? I've seen it being used both with and without the using statement.

I'm specifically going to use the EF context from within a WCF service method, create the context, do some linq and return the answer.

EDIT: Seems that I'm not the only one wondering about this. Another question is what's really happening inside the Dispose() method. Some say it closes connections, and some articles says not. What's the deal?

Johan Danforth
  • 4,469
  • 6
  • 37
  • 36

9 Answers9

36

If you create a context, you must dispose it later. If you should use the using statement depends on the life time of the context.

  1. If you create the context in a method and use it only within this method, you should really use the using statement because it gives you the exception handling without any additional code.

  2. If you use the context for a longer period - that is the life time is not bound by the execution time of a method - you cannot use the using statement and you have to call Dispose() yourself and take care that you always call it.

What does Dispose()do for an object context?

I did not look at the code, but at least I exspect it to close the database connection with its underlying sockets or whatever resources the transport mechanism used.

Daniel Brückner
  • 59,031
  • 16
  • 99
  • 143
5

Per Progamming Entity Framework: "You can either explicitly dispose the ObjectContext or wait for the garbage collector to do the job."

So in short, while the using statement isn't required, it's best practice if you know you're done using the ObjectContext since the resource is freed up immediately instead of waiting for garbage collection.

Cory House
  • 14,235
  • 13
  • 70
  • 87
  • GC was made to **not** dispose things explicitely. It a must (if possible) to dispose objects which reference unmanaged resources. So the real question here - does EF context reference an unmanaged resource? If not then you shouldnt dispose it... – Boppity Bop Nov 03 '15 at 14:52
4

Since you don't know when the garbage collector disposes an item, it's always good to wrap up objects that implement IDisposable in a using-block if you know when you're done with it.

ullmark
  • 2,469
  • 1
  • 19
  • 28
3

EF5 and before version

    using { ...
            // connecction open here.

            ...
            context.Blogs.Add(blog); 
            context.SaveChanges();   // query etc now opens and immediately closes 

            ...
            context.Blogs.Add(blog); 
            context.SaveChanges();   // query etc now opens and immediately closes 
   }

EF6 and after version

 using {
        // connecction open here.

        ...
        context.Blogs.Add(blog); 
        context.SaveChanges(); 

        // The underlying store connection remains open for the next operation  

        ...
        context.Blogs.Add(blog); 
        context.SaveChanges(); 

        // The underlying store connection is still open 

   } // The context is disposed – so now the underlying store connection is closed

Reference: http://msdn.microsoft.com/en-us/data/dn456849#open5

Tieson T.
  • 20,774
  • 6
  • 77
  • 92
  • 2
    This is wrong or misleading. The article you referenced is about managing connection, about MANUALLY calling `connection.Open()` (and you dont translate it to your example code), not about `Dispose()`. If you dont call `connection.Open()` manually (you leave it to EF connection management), connection is closed at your `// The underlying store connection is still open`. Nothing to do with OP question. – Jan 'splite' K. Jan 06 '17 at 08:33
1

I realy tested this thing for both ADO.net and EF v.6 and watched connections in SQL table

select * from sys.dm_exec_connections

Methods to be tested looked like this:

1) ADO.net with using

  using(var Connection = new SqlConnection(conString))
  {
    using (var command = new SqlCommand(queryString, Connection))
    {    
       Connection.Open();
       command.ExecuteNonQueryReader();
       throw new Exception()  // Connections were closed after unit-test had been 
       //finished.  Expected behaviour
     }
  }

2) ADO.net withour using

var Connection = new SqlConnection(conString);
using (var command = new SqlCommand(queryString, Connection))
{
    Connection.Open();
     command.ExecuteNonQueryReader();
    throw new Exception() // Connections were NOT closed after unit-test had been finished

     finished.  I closed them manually via SQL.  Expected behaviour
    }

1) EF with using.

 using (var ctx = new TestDBContext())
    {
        ctx.Items.Add(item);
        ctx.SaveChanges();
        throw new Exception() // Connections were closed, as expected.

     }

2) EF without using

 var ctx = new TestDBContext();             
 ctx.Items.Add(item);
 ctx.SaveChanges();
 throw new Exception() // Connections WERE successfully closed, as NOT expected.

I don't know why is it so, but EF automatically closed connections. Also All the patterns of repository and UnitOfWork which use EF don't use using. It's very strange for me, because DBContext is Disposable type, but it's a fact.

Maybe in Microsoft they did something new for handling?

Artem A
  • 2,154
  • 2
  • 23
  • 30
  • Actually its simple: If you dont manually open connection (like `ctx.Database.Connection.Open();`) EF6 take care of it and will manage open / close with every query (see ADO connection pooling why this is not a bad idea). But if you open it manually, EF6 will consider you know what you are doing and leave it open. – Jan 'splite' K. Jan 06 '17 at 08:42
  • You answered not about the topic of my comment. There is no manually opened connection for EF. All glue in comments in code – Artem A Jan 11 '17 at 19:48
1

Always, if you instantiate a class that implements IDisposable, then you are responsible for calling Dispose on it. In all but one case, this means a using block.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • 2
    True, but the question is what the Dispose() method relly does for the EF context. It seems that it's not really _that_ important from what I can find on the topic! – Johan Danforth May 05 '09 at 11:00
  • 3
    Thanks for asking this question. As a result, I found that all the Dispose calls that I'm worried about forgetting in our application might not be as critical as I feared (by reading http://lee.hdgreetings.com/2008/06/linq-datacontex.html). – BlueMonkMN May 05 '09 at 11:08
  • The article is about LINQ to SQL and I am not sure if the Entity Framework does not keep an open connection. – Daniel Brückner May 05 '09 at 11:15
  • ... that said, I'll still probably return code for more work during my reviews if I see a DataContext being used that I can determine is not being disposed of properly. I think it's cleaner to dispose of all disposable objects if you can remember to do so. – BlueMonkMN May 05 '09 at 11:15
  • 1
    Although I'm using a DataContext, I assume EF also tracks object changes which is probably the larger resource in both cases. – BlueMonkMN May 05 '09 at 11:16
  • Since you won't know when Microsoft will change DataContext so that there's something to Dispose that you actually _care_ about, I suggest always disposing. The fact that a class has implemented IDisposable implies that it wants you to call Dispose. Be a good developer and do what the nice class asked you to do, ok? ;-) – John Saunders May 05 '09 at 11:19
  • 1
    I just had a quick look at the DataContext class and the cited article seems plain wrong - DataContext.Dispose() tries to close an underlying connection. (May be I am wrong and the connection is usually closed, but at least it tries to close it. And I cannot imagine that LINQ to SQL creates a new connection for every request because of the performance impact, so I tend to believe that the connection will be open while the data context is alive.) – Daniel Brückner May 05 '09 at 11:48
  • Well, I guess I could (and I do now, I'm a code reviewer myself), but the question is WHAT's happening in Dispose() really? Does it flush the edmx model from memory? – Johan Danforth May 05 '09 at 11:53
  • 4
    @Johan: it doesn't matter what it does today. It's not your code. It could change tomorrow. Given that you are depending on today's implementation, it probably _should_ change tomorrow, just to teach you why not! – John Saunders May 05 '09 at 12:49
1

When you dispose, the ObjectContext disposes other owned objects.

Including things like the EntityConnection which wraps the actual database connection, i.e. generally a SqlConnection.

So 'if' the SqlConnection is open it will be closed when you dispose the ObjectContext.

Alex James
  • 20,874
  • 3
  • 50
  • 49
0

I have noticed (although in only one application) that the explicit disposal was causing thread abort exceptions in mscorlib which are caught before the application code, but at least in my case resulting in a noticeable performance hit. Haven't done any significant research on the issue, but probably something worth consideration if you are doing this. Just watch your DEBUG output to see if you are getting the same result.

0

If Dispose closes connection to DB it is a bad idea to call it. For example in ADO.NET connections are in connection pool and never be closed before timeout or application pool stop.

Ilya
  • 51
  • 3