Search code examples
asp.netvb.net

DataContext Disposal error resolved but why?


I am working with VB.Net. I have resolved a behavior where the code returns with an error

Cannot access a disposed object. Object name: 'DataContext accessed after Dispose.'

My problem: I simply don't understand why it works!

Here is my code when the error happens:

Public Function Element_Import(ByVal id_element As Integer) As elements

    Using db As New GlobalDataContext(MyConnexion)

        Return (From element In db.elements
                Select element
                Where element.id_element = id_element).First
    End Using

End Function

Then I try to retrieve the data :

Dim myElement As elements = _MyConnection.Element_Import(id_element)
Dim myLocal As List(Of elements_localisation) = myElement.elements_localisation.ToList '-- ObjectDisposedException !

When I import my element then try to access sub-tables called "elements_localisation" and "elements_files" an ObjectDisposedException occures. That's fair as the DataContext is not available.

So I have done something different :

 Public Function Element_ImportContext(ByVal id_element As Integer) As elements
    Dim myElement As elements
    Dim myElementLocalisation As New List(Of elements_localisation)
    Dim myElementFiles As New List(Of elements_files)
    Using db As New GlobalDataContext(MyConnexion)
        myElement = (From element In db.elements
                Select element
                Where element.id_element = id_element).First

        myElementLocalisation = myElement.elements_localisation.ToList
        myElementFiles = myElement.elements_files.ToList
    End Using
    Return myElement

End Function

Then I try to retrieve the data :

Dim myElement As elements = _MyConnection.Element_ImportContext(id_element)
Dim myLocal As List(Of elements_localisation) = myElement.elements_localisation.ToList '-- IT WORKS !

I really want to understand what happened as, in both case, the DataContext is disposed.

Can anyone explain this to me?


Solution

  • When you write LINQ, you write a query to be executed against some data, that query is only executed when another part of the code needs the data.

    In your case, you are returning the myElement variable because you have used .First(), which forces the query to be executed and the first item to be returned.

    The properties elements_localisation and elements_files are likely to be virtual properties that are only loaded when you request them. (This is certainly the case with Entity Framework, I'm not sure what you're using here).

    Your program will try to access the virtual property which will then go off to the data context to get the next bit of data you requested, but in your case the data context is disposed.

    Your second approach works because you have used ToList() on the virtual properties, which forces the data to be retrieved then and there, before your data context has been disposed.