Reputation: 20769
I have a repeater of controls on an aspx page. I am trying to move a query out of the control and into the parent page as there is a massive hit on the DB for each control. The problem is that I get the following error.
Cannot access a disposed object.
Object name: 'DataContext accessed after Dispose.'.
I don't understand this as I thought that doing .ToList() forces the query to be executed
My code in the Parent page
Private _activityList As IEnumerable(Of Activity)
Public ReadOnly Property ActivityList() As IEnumerable(Of Activity)
Get
Return _activityList
End Get
End Property
Sub PopulatePage()
Dim activityList = From a In dbContext.Activities Where a.PA.PA_Key.ToUpper().Trim() = "DCC" _
Select a
_activityList = activityList.AsEnumerable()
End Sub
The code in my control is:
Public _activityList As List(Of Activity)
Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
_activityList = CType(Me.Page, ParentPage).ActivityList.ToList()
End Sub
Sub grdSelectedActivities_NeedDataSource(ByVal source As Object, ByVal e As Telerik.WebControls.GridNeedDataSourceEventArgs) Handles grdSelectedActivities.NeedDataSource
Dim lnqActivities = _activityList
Dim objActivity As Activity = (From x In lnqActivities Where x.AC_Code = ActivityCode Select x).Single
Dim lnqRoundActivities = (From roundactivity In objActivity.RoundActivities Where roundactivity.RA_DS_Code = DepartmentalSettingsCode
Select roundactivity Order By roundactivity.RA_Name)
grdSelectedActivities.DataSource = lnqRoundActivities
End Sub
EDIT
I think that is is failing as it is trying to get RoundActivities in the grdSelectedActivities_NeedDataSource
control method. Therefore I need to send an Activities object which has RoundActivityies child objects.
I have tried to create this object but get the following error:
Explicit construction of entity type 'Activity' in query is not allowed.
enter code here
This is the updated code:
Dim activityList = (From a In dbContext.Activities Where a.PA.PA_Key.ToUpper().Trim() = "DCC" Select New Activity With {.AC_Code = a.AC_Code, .RoundActivities = a.RoundActivities})
Solution:
I followed @kristoferA advice and did the following
Dim loadOptions = New DataLoadOptions()
loadOptions.LoadWith(Of Activity)(Function(a As Activity) a.RoundActivities)
loadOptions.AssociateWith(Of Activity)(Function(a As Activity) a.RoundActivities.Where(Function(z) If(z.RA_DS_Code = departmentCode, False)))
dataContext.LoadOptions = loadOptions
Upvotes: 2
Views: 808
Reputation: 3939
I guest that the dbContext get disposed after PopulatePage() done and your Linq select return type is IEnumerable(Of Activity) which's just a prepared SQL statement.
try..
_activityList = activityList.ToList()//.AsEnumerable()
if your Model is stateless you can create new dbContext then enumerate and dispose it.
Using db As New dbContext()
Dim activityList = (From a In dbContext.Activities Where a.PA.PA_Key.ToUpper().Trim() = "DCC" _
Select a).ToList()
_activityList = activityList.ToList()
End Using
Upvotes: 0
Reputation: 12397
Sounds like you are lazy loading some association.
Turn off lazy loading (dc.DeferredLoadingEnabled = false), and pass a DataLoadOptions object to dc.LoadOptions to instruct the DC what you want to eager load.
Upvotes: 1
Reputation: 11894
ai.farfa is correct with the ToList(). That is the call that trigger the actual query. I think you should do it on this line though :
grdSelectedActivities.DataSource = lnqRoundActivities.ToList()
Upvotes: 0