Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should I dispose of a data context

I'm currently writing a data access layer for an application. The access layer makes extensive use of linq classes to return data. Currently in order to reflect data back to the database I've added a private data context member and a public save method. The code looks something like this:

private DataContext myDb; public static MyClass GetMyClassById(int id) {     DataContext db = new DataContext();     MyClass result = (from item in db.MyClasss                       where item.id == id                       select item).Single();     result.myDb = db;     return result; }  public void Save() {     db.SubmitChanges(); } 

That's a gross over simplification but it gives the general idea. Is there a better way to handle that sort of pattern? Should I be instantiating a new data context every time i want to visit the db?

like image 430
Mykroft Avatar asked Dec 23 '08 19:12

Mykroft


People also ask

When should you call Dispose?

There is a simple guideline: if you have finished with an object whose type implements IDisposable then call Dispose() on it; you should use a using block to do this.

Should I Dispose Datacontext?

So you should always Dispose any object which implements IDisposable. In the case of Controllers and DataContexts, this turns out to be really easy, because Controller also implements IDisposable, and hence has a virtual Dispose method you can override.

What is the use of Dispose method?

The Dispose method performs all object cleanup, so the garbage collector no longer needs to call the objects' Object. Finalize override. Therefore, the call to the SuppressFinalize method prevents the garbage collector from running the finalizer. If the type has no finalizer, the call to GC.

Is Dispose method called automatically?

Dispose() will not be called automatically. If there is a finalizer it will be called automatically. Implementing IDisposable provides a way for users of your class to release resources early, instead of waiting for the garbage collector.


2 Answers

It actually doesn't matter too much. I asked Matt Warren from the LINQ to SQL team about this a while ago, and here's the reply:

There are a few reasons we implemented IDisposable:

If application logic needs to hold onto an entity beyond when the DataContext is expected to be used or valid you can enforce that contract by calling Dispose. Deferred loaders in that entity will still be referencing the DataContext and will try to use it if any code attempts to navigate the deferred properties. These attempts will fail. Dispose also forces the DataContext to dump its cache of materialized entities so that a single cached entity will not accidentally keep alive all entities materialized through that DataContext, which would otherwise cause what appears to be a memory leak.

The logic that automatically closes the DataContext connection can be tricked into leaving the connection open. The DataContext relies on the application code enumerating all results of a query since getting to the end of a resultset triggers the connection to close. If the application uses IEnumerable's MoveNext method instead of a foreach statement in C# or VB, you can exit the enumeration prematurely. If your application experiences problems with connections not closing and you suspect the automatic closing behavior is not working you can use the Dispose pattern as a work around.

But basically you don't really need to dispose of them in most cases - and that's by design. I personally prefer to do so anyway, as it's easier to follow the rule of "dispose of everything which implements IDisposable" than to remember a load of exceptions to it - but you're unlikely to leak a resource if you do forget to dispose of it.

like image 52
Jon Skeet Avatar answered Oct 07 '22 03:10

Jon Skeet


Treat your datacontext as a resource. And the rule of using resource says

"acquire a resource as late as possible, release it as soon as its safe"

like image 36
Perpetualcoder Avatar answered Oct 07 '22 03:10

Perpetualcoder