Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EntityFramework context dispose

I wrote several Applications which works with entity framework. I used to work with using clause. With this clause, i am sure the database connexion is closed properly.

But, in some cases, my Database context object is a field of a class. Its instantiation is in the declaration, and there is no using clause.

I've just discovered that, in this case, Dispose() method is not called. With using clause, Dispose() is called automatically

So my question is: What happens if Dispose() is not called on database context ? The destructor is called so do you think database will be closed by destructor ? Or should i call Dispose() manually on the destructor of the container object like this:

class MyClass
{
    public MyDbContext ctx = new MyDbContext();

    ....

    ~MyClass()
    {
         ctx.Dispose();
    }
}

Thanks

like image 958
Bob5421 Avatar asked Mar 11 '23 03:03

Bob5421


2 Answers

If you can use using on your parent class, then make it to implement IDisposable:

class MyClass : IDisposable
{
    public MyDbContext ctx = new MyDbContext();

    ....

    public void Dispose()
    {
        ctx.Dispose();
    }
}

This way, calling your parent class in a using statement will dispose your context when exiting it.

like image 38
Benjamin Soulier Avatar answered Apr 05 '23 11:04

Benjamin Soulier


You must not call Dispose at all. Specially explicitly.

When you use using it is an implicit Dispose() in a try-finally block. Which is fine.But you don't need to do it explicitly.

Why ?

A separate or explicit Dispose statement can be missed when an exception occurs earlier.So there is no guarantee about the explicit Dispose.

Here it is from Rowan Miller [MSFT] :

The default behavior of DbContext is that the underlying connection is automatically opened any time is needed and closed when it is no longer needed. E.g. when you execute a query and iterate over query results using “foreach”, the call to IEnumerable.GetEnumerator() will cause the connection to be opened, and when later there are no more results available, “foreach” will take care of calling Dispose on the enumerator, which will close the connection. In a similar way, a call to DbContext.SaveChanges() will open the connection before sending changes to the database and will close it before returning.

Given this default behavior, in many real-world cases it is harmless to leave the context without disposing it and just rely on garbage collection.

That said, there are two main reason our sample code tends to always use “using” or dispose the context in some other way:

  1. The default automatic open/close behavior is relatively easy to override: you can assume control of when the connection is opened and closed by manually opening the connection. Once you start doing this in some part of your code, then forgetting to dipose the context becomes harmful, because you might be leaking open connections.

  2. DbContext implements IDiposable following the recommended pattern, which includes exposing a virtual protected Dispose method that derived types can override if for example the need to aggregate other unmanaged resources into the lifetime of the context.

You can read more about it here : Do I always have to call Dispose() on my DbContext objects? Nope

Managing DbContext the right way with Entity Framework

like image 126
Sampath Avatar answered Apr 05 '23 12:04

Sampath