1

I'm new to Linq to EntityFramework, one question in Linq2EntityFramework I have is when or if to dispose the ObjectContext. The reason I ask this question is that normally in my DAL I have code like

public List<User>  GetUsers()
{
    using (MyEntities db = new MyEntities())   //where MyEntities inherits ObjectContext. 
    {

       // do some linq select operation which returns IQueryable<User>
       // call ToList() on the return IQueryable which is when the DB is really accessed
       // then we return List<User>

    } 
    // after using statement a Dispose method on ObjectContext is called, hence disposed the ObjectContext,  and in turn it closes my DB connection and releases it to the pool
}

Now, I don't want to do this, I want my DAL return IQueryable to my BLL instead of List, so that my BLL can do filtering like Skip() on the returned IQueryable then call ToList() in the BLL. So the code becomes like this,

public IQueryable<User>  GetUsers()
{
   // do some linq select operation which returns IQueryable<User>
   // then just return what we got back
   // Note: no DB access occurred here, this is called deferred execution, because the real DB access happens later in BLL
}

Then in my BLL I have a method like

public List<User>  GetUsers()
{
   // get IQueryable<User> from DAL to a var say users     
    return  users.Skip(10).Take(20).ToList(); // here the DB access really happens.  Note: if we put using in DAL, here will throw exception saying DB is already closed!!
}

My questions are,

  1. If I use the second approach, will Linq2EF know to close my connection after the above method finishes?
  2. With the second approach, ObjectContext is never Disposed, would this be a problem on large sites?
  3. Or how do I get IQuerayable back but still dispose the ObjectContext in DAL?

Thank you so much, Ray.

Edit: One thing I don't understand is that if the connection is smartly managed by the ObjectContext, then is it OK to just not disposing the ObjectContext? What other things beside the ObjectContext manage?

4 Answers 4

2

Regarding your questions:

  1. It will close the open and close the connection with the ToList, since all the enumeration is happening at that place. Only place this can get you with a long opened connection, is if you enumerate over it and run some semi-long processing for each item.
  2. For normal large sites and normal operations, you will be ok with this. The main thing that can get you into trouble is entity tracking, which involves any entity you have loaded. If you are either loading too much information or have a very large site, you can avoid using it (don't sweat it for a normal site).
  3. You can have your data access class implement IDisposable, and dispose the datacontext when it is being disposed. So in your GetUsers you can put an using around your data access class instead.
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you for the reply and I agree with you! I did more research, there are a couple guys mentioned if they don't dispose the ObjectContext, it caused unwanted locking in DB. I guess if you share context and never dispose it, the entity tracking could be complex to get right.
To be complete, I read the 2 guys having problem sharing context stackoverflow.com/questions/20047/….
In that post, Jeff said "we are sharing one static datacontext in the base Controller for the most part." Then someone points out Controllers only live for a single request - so at the end of processing a request they are garbage collected. I guess when that happens, the context is disposed.
@ray247 added a comment to stackoverflow.com/questions/20047/… to clear it up, as the property posted isn;t really static, so it lives with the instance of the controller
the result of the question/answer was that they changed to use snapshot isolation, no change to the property in the base controller - from that you can tell they are letting it be garbage collected (no dispose).
|
1

I tend to think of the EF ObjectContext as the DAL, which gets around this issue. If you want your own DAL to encapsulate the EF stuff (not a horrible idea, IMO), I would suggest making your DAL implement IDisposable.

Comments

1

If you are in the context of a website, you should seriously consider making it so that your ObjectContext is alive throughout the request.

You need to keep the ObjectContext around for lazy loading, now way around that.

Connections are opened and closed as needed during queries and SaveChanges, so you should not have a "connection leak".

2 Comments

Thanks a lot for the comment on the connection. By keep ObjectContext alive, do you mean it is okay for me not to dispose it, or in other words, I'm free from surrounding code with using statsment?
No, it should be instantiated once and disposed at the end of the request cycle. It's pretty easy to do if you are in a webservice, maybe trickier in a WebForms app. You should still dispose the context, but all operations in a request should be carried out on one context.
0

if you want and IQueryable you can do this by querying against the ToList() result and return that

2 Comments

I think that doing the ToList would cause the IQueryable to enumerate the results and that would cause the read at that point. Ray247 is trying to avoid hitting the database to early hence retuning IQueryable objects rather than List objects.
Thanks Pervez for the clarification! I think if I don't get definite answer on this one, I'll go with traditional approach where I surround every operation in my DAL with using and return List<> instead of IQueryable<>. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.