views:

145

answers:

3

Can someone please explain the below to me. First is how I call the method and the second bit is the LINQ Method.

My curiousity stems from the fact that I get a context error if I un-comment the using portion.

Why? I apparently do not fully understand using and context's. And I would like to better understand this.

Guid workerID = new Guid(new ConnectDAL.DAL.Security().GetUserIDByUserLogin(HUD.CurrentUser));

        var myMembers = BLLCmo.GetAllMembers(workerID);
        if (myMembers.Rows.Count != 0)
        {
            dgvMyMembers.DataSource = myMembers;
        }
        else
        {
            var allMembers = BLLCmo.GetAllMembers();
            dgvMyMembers.DataSource = allMembers;
        }




    internal static CmoDataContext context = new CmoDataContext();

    public static DataTable GetAllMembers()
    {
        DataTable dataTable;

        //using (context)
        //{
            var AllEnrollees = from enrollment in context.tblCMOEnrollments
                               select new
                                       {
                                           enrollment.ADRCReferralID,
                                           enrollment.ClientID,
                                           enrollment.CMONurseID,
                                           enrollment.CMOSocialWorkerID,
                                           enrollment.DisenrollmentDate,
                                           enrollment.DisenrollmentReasonID,
                                           enrollment.EconomicSupportWorkerID,
                                           enrollment.EnrollmentDate
                                       };

            dataTable = AllEnrollees.CopyLinqToDataTable();
        //}
        return dataTable;
    }
+6  A: 

"using" blocks automatically dispose of the object you're using. Since you didn't give further details on what the exact error is, I'm betting its related to the fact that the "using" will dispose of your "context", and then later you'll try to use your context again.

Data Contexts should be used atomically. They're already internally coded to be efficient that way, there's usually no justifiable reason to have one as long-running as you do. The reason you see most samples that use a "using" is because they have the data context initialized immediately before the using (or in it) and then don't try to referenced the disposed context.

As a final note, disposing of objects causes them to release all their internal memory references (such as open connections, cached data, etc).

//Our context exists right now ... unless we've already called this method since the app started ;)
var myMembers = BLLCmo.GetAllMembers(workerID); // Context is disposed at the end of this call
if (myMembers.Rows.Count != 0)
{
  dgvMyMembers.DataSource = myMembers;  //No prob, we didn't call our function again
}
else
{
  var allMembers = BLLCmo.GetAllMembers();  // Oops, our context was disposed of earlier
  dgvMyMembers.DataSource = allMembers;
}
JustLoren
I still am not understanding. I understand that `usings` dispose of "things", what I am not understanding is why my calling code CARES? I am assinging the data to a DataTable and am only accessing the Context in the DAL on the call so I don't understand the "long running" part.
Refracted Paladin
"internal static CmoDataContext context = new CmoDataContext();" means that your context is only ever initialized once. You call GetAllMembers() twice in a row. The first time you call it, your context has been initialized and is good to go. the second time you call it, it is disposed.Your problems would be solved if you moved your context's scope to the function level.
JustLoren
Because the context is static, the second time you try to access it it's already disposed. Hence the error.
bruno conde
Thank you. I could have swore I had read a tutorial that declared a static context like that but I cannot find it now and what you say makes sense.
Refracted Paladin
+2  A: 

You get an error if you use using because the context is disposed the second time it's called by GetAllMembers().

If you need to dispose the context I sugest you create one on the fly in the GetAllMembers() as opposed to having a static context.

Check out the documentation of IDisposable and using.

Here's a link to an article that might help you with Lifetime Management of DataContext.

bruno conde
I think you have answered MY question. Because I have the `STATIC context` outside of the `Method` the Second call doesn't have a `context`. Correct?
Refracted Paladin
That's correct.
bruno conde
+2  A: 

I have had this problem and did not understand it either at that time. I just removed the using and it worked. The problem was Lazy Loading. The DataContext gave me an entity, but later I tried accessing a property of a parent entity (in the sense of a Foreign Key). Because this parent entity was not loaded the first time, it tried to get it but the DataContext was gone. So I used a DataLoadOptions. If I knew I needed a related entity, I loaded it with the original entity.

Ex: You ask for an invoice to your datacontext, but later you want to access the client's name, like in invoice.Client.Name. The client has not been loaded, so the name is not available.

DataLoadOptions are also important for performance, if you need this related entity in a loop, you'll go back to the DB as many times as you loop if you do not pre-load the child (or parent) entity.

devMomentum